# API Documentation

Welcome to the AutoContent API documentation! Generate AI-powered podcasts, videos, and more with our comprehensive API.

## 🚀 Quick Start Guides

Get started with AutoContent API in minutes! Choose from these step-by-step guides:

### [🎧 Create a Podcast Episode](/quick-start/podcasts/create-podcast-episode)

Generate your first AI-powered podcast episode from web resources, YouTube videos, or text content. Perfect for beginners!

### [🐦 Create a Podcast from X Feed](/quick-start/podcasts/create-feed-podcast)

Set up feeds from X (Twitter) accounts and automatically generate podcasts from the latest posts. Great for news and social media content.

### [🔬 Create a Research-Based Podcast](/quick-start/deep-researches/create-research-podcast)

Perform deep research on any topic and generate comprehensive, in-depth podcast episodes from your findings.

### [🎬 Create an Explainer Video](/quick-start/explainer-videos/create-explainer-video)

Turn research links, PDFs, or scripts into narrated motion graphics using `outputType: "video"` and optional branding prompts.

### [🖼️ Create an Infographic](/quick-start/infographics/from-text)

Generate visual one-pagers from text or URLs with `outputType: "infographic"` and control orientation and detail.

### [🧪 Create a Quiz](/quick-start/quizzes/from-text)

Generate quizzes with `outputType: "quiz"` and set the difficulty level for question depth.

### [📊 Create a Data Table](/quick-start/data-tables/create-data-table)

Generate spreadsheet-ready tables with `outputType: "datatable"` and download the completed `.xlsx` file from `/data-tables/{id}/download`.

### [🗂️ Create a Slide Deck](/quick-start/slide-decks/from-text)

Build decks from text with `outputType: "slide_deck"` and pick `slideDeckFormat` (`detailed` or `presenter`).

### [📄 Create a Briefing Document](/quick-start/documents/create-document)

Generate NotebookLM-style briefings from websites, PDFs, or internal notes and choose `pdf`, `html`, or `text` output.

### [🔒 Private Notebooks](/private-notebooks)

Keep reusable sources in a dedicated notebook and ask grounded questions with citations.

### [🎬 Create a Video Short](/quick-start/video-shorts/create-video-short)

Generate AI-powered video shorts with talking avatars from text content, perfect for social media and educational content.

### [🔍 Start Deep Research](/quick-start/deep-researches/start-deep-research)

Kick off long-form research you can reuse across podcasts, decks, and infographics.

### [🧩 Create a Project (Brand Assets)](/quick-start/tools/create-project)

Store logos and brand colors once, then reuse them across videos, infographics, quizzes, and slide decks.

### [📝 Transcribe Audio](/quick-start/tools/transcribe-audio)

Turn uploaded audio, hosted files, or existing episodes into reusable transcripts for downstream workflows.

### [📤 Upload Private Files](/quick-start/tools/upload-files)

Upload private PDFs and other source files to `/files`, then reuse the returned file IDs in document workflows.

### [🧭 Track Requests & Status Codes](/quick-start/tools/track-requests)

Understand `request_id` vs `requestId`, poll `/content/Status/{id}`, and handle shared async job patterns cleanly.

### [💻 Explore Language Code Samples](/code-samples)

Copy-paste requests for C#, Node.js, Java, PHP, and Python across every content type.

***


# Content

Content operations and usage information

## Get usage information

> Returns current usage statistics and remaining credits

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Usage":{"type":"object","properties":{"allowed":{"type":"integer","description":"Total credits allowed"},"used":{"type":"integer","description":"Total credits used"},"allowedDailyPodcasts":{"type":"integer","description":"Daily podcast limit"},"usedDailyPodcasts":{"type":"integer","description":"Podcasts created today"}}}}},"paths":{"/content/Usage":{"get":{"summary":"Get usage information","description":"Returns current usage statistics and remaining credits","tags":["Content"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Get queued and processing request counts

> Returns lightweight queue counts for the authenticated client. Active means queued + processing.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"QueueStats":{"type":"object","properties":{"success":{"type":"boolean"},"queued":{"type":"integer","description":"Requests waiting to be picked up for processing"},"processing":{"type":"integer","description":"Requests currently in progress"},"active":{"type":"integer","description":"queued + processing"}}}}},"paths":{"/content/QueueStats":{"get":{"summary":"Get queued and processing request counts","description":"Returns lightweight queue counts for the authenticated client. Active means queued + processing.","tags":["Content"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueueStats"}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Get queued or processing request IDs

> Returns paginated request IDs and lightweight request metadata for the authenticated client.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"QueueRequestsResponse":{"type":"object","properties":{"success":{"type":"boolean"},"state":{"type":"string","enum":["queued","processing","active"]},"ids":{"type":"array","items":{"type":"string"}},"items":{"type":"array","items":{"$ref":"#/components/schemas/QueueRequestSummary"}},"count":{"type":"integer","description":"Number of items in this page"},"total_count":{"type":"integer"},"page":{"type":"integer"},"page_size":{"type":"integer"},"total_pages":{"type":"integer"}}},"QueueRequestSummary":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"integer"},"request_type_id":{"type":"integer"},"output_type":{"type":"string","nullable":true},"requested_on":{"type":"string","format":"date-time","nullable":true},"processing_on":{"type":"string","format":"date-time","nullable":true},"scheduled_on":{"type":"string","format":"date-time","nullable":true}}}}},"paths":{"/content/QueueRequests":{"get":{"summary":"Get queued or processing request IDs","description":"Returns paginated request IDs and lightweight request metadata for the authenticated client.","tags":["Content"],"parameters":[{"in":"query","name":"state","required":false,"schema":{"type":"string","enum":["queued","processing","active","all"],"default":"active"},"description":"Request state to fetch. `active` means queued + processing; `all` is accepted as an alias for active."},{"in":"query","name":"page","schema":{"type":"integer","minimum":1,"default":1},"required":false,"description":"Page number for pagination, starting at 1."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"description":"Number of items per page."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueueRequestsResponse"}}}},"400":{"description":"Invalid state"},"401":{"description":"Unauthorized"}}}}}}
```

## Get all podcasts

> Returns all podcasts created by the current client, optionally filtered by status. Supports optional pagination.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Podcast":{"type":"object","properties":{"id":{"type":"string","description":"Podcast ID"},"requestTypeId":{"type":"integer","description":"Type of podcast request"},"audioTitle":{"type":"string","description":"Title of the podcast"},"audioUrl":{"type":"string","description":"URL to the audio file"},"responseText":{"type":"string","description":"Podcast transcript/text"},"requestedOn":{"type":"string","format":"date-time","description":"When the podcast was requested"},"succeededOn":{"type":"string","format":"date-time","description":"When the podcast was completed"},"errorOn":{"type":"string","format":"date-time","description":"When the podcast failed (if applicable)"},"processingOn":{"type":"string","format":"date-time","description":"When the podcast started processing (if applicable)"},"errorMessage":{"type":"string","description":"Error message if the podcast failed"},"status":{"type":"integer","description":"Current status of the podcast"},"shareUrl":{"type":"string","description":"Public sharing URL for the podcast"}}}}},"paths":{"/content/Podcasts":{"get":{"summary":"Get all podcasts","description":"Returns all podcasts created by the current client, optionally filtered by status. Supports optional pagination.","tags":["Content"],"parameters":[{"in":"query","name":"status","required":false,"schema":{"type":"string","enum":["all","queued","failed","succeeded","processed"],"default":"all"},"description":"Filter podcasts by status (all=all podcasts, queued=status=0 and no error, failed=has errorOn, succeeded=status=100, processed=has processingOn)"},{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"required":false,"description":"Page number for pagination (starts at 1). If not provided, returns all results."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"description":"Number of items per page (max 100, default 50 if page is specified)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"array","description":"Non-paginated response (when page and limit are not provided)","items":{"$ref":"#/components/schemas/Podcast"}},{"type":"object","description":"Paginated response (when page or limit are provided)","properties":{"podcasts":{"type":"array","items":{"$ref":"#/components/schemas/Podcast"}},"totalCount":{"type":"integer","description":"Total number of podcasts"},"page":{"type":"integer","description":"Current page number"},"pageSize":{"type":"integer","description":"Number of items per page"},"totalPages":{"type":"integer","description":"Total number of pages"}}}]}}}},"400":{"description":"Invalid status parameter"},"401":{"description":"Unauthorized"}}}}}}
```

## Get all transcripts

> Returns all transcripts created by the current client, optionally filtered by status. Supports optional pagination.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Transcript":{"type":"object","properties":{"id":{"type":"string","description":"Transcript ID"},"audioTitle":{"type":"string","description":"Title of the original audio"},"audioUrl":{"type":"string","description":"URL to the original audio file"},"responseText":{"type":"string","description":"The transcript text content"},"requestedOn":{"type":"string","format":"date-time","description":"When the transcript was requested"},"succeededOn":{"type":"string","format":"date-time","description":"When the transcript was completed"},"errorOn":{"type":"string","format":"date-time","description":"When the transcript failed (if applicable)"},"processingOn":{"type":"string","format":"date-time","description":"When the transcript started processing (if applicable)"},"errorMessage":{"type":"string","description":"Error message if the transcript failed"},"status":{"type":"integer","description":"Current status of the transcript"},"language":{"type":"string","description":"Language of the transcript"},"callbackData":{"type":"string","description":"Optional callback data provided during request"},"scheduledOn":{"type":"string","format":"date-time","description":"When the transcript was scheduled"}}}}},"paths":{"/content/Transcripts":{"get":{"summary":"Get all transcripts","description":"Returns all transcripts created by the current client, optionally filtered by status. Supports optional pagination.","tags":["Content"],"parameters":[{"in":"query","name":"status","required":false,"schema":{"type":"string","enum":["all","queued","failed","succeeded","processed"],"default":"all"},"description":"Filter transcripts by status (all=all transcripts, queued=status=0 and no error, failed=has errorOn, succeeded=status=100, processed=has processingOn)"},{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"required":false,"description":"Page number for pagination (starts at 1). If not provided, returns all results."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"description":"Number of items per page (max 100, default 50 if page is specified)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"array","description":"Non-paginated response (when page and limit are not provided)","items":{"$ref":"#/components/schemas/Transcript"}},{"type":"object","description":"Paginated response (when page or limit are provided)","properties":{"transcripts":{"type":"array","items":{"$ref":"#/components/schemas/Transcript"}},"totalCount":{"type":"integer","description":"Total number of transcripts"},"page":{"type":"integer","description":"Current page number"},"pageSize":{"type":"integer","description":"Number of items per page"},"totalPages":{"type":"integer","description":"Total number of pages"}}}]}}}},"400":{"description":"Invalid status parameter"},"401":{"description":"Unauthorized"}}}}}}
```

## Create new content

> Generate new content based on resources, topic, feed selections, researches, YouTube channels, or linked podcast episodes. Use video metadata fields (titlePrompt, descriptionPrompt, thumbnailImagePrompt, introImagePrompt, voices, publishTargets, format) when outputType is video. Video requests ignore the generic duration field if it is provided. Set isScheduled or templateMode to create recurring templates instead of immediate processing.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"ContentRequest":{"type":"object","required":["outputType"],"properties":{"resources":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["text","youtube","website","pdf","file"]},"content":{"type":"string","description":"For type \"file\", provide an https URL or a file id returned by POST /files. For other types, provide the text or URL expected by that type."}}},"description":"Resources for content generation (required if topic, feedSelections, or researches are not provided)"},"topic":{"type":"string","description":"Topic for content generation (alternative to resources, feedSelections, or researches)"},"feedSelections":{"type":"array","description":"Cached feed items to include in the request (alternative to resources, topic, or researches)","items":{"$ref":"#/components/schemas/FeedSelection"}},"researches":{"type":"array","items":{"type":"string"},"description":"Array of research IDs to include as text resources (max 10)"},"projects":{"type":"array","items":{"type":"string"},"description":"Array of project IDs to use as context for generation (max 10)"},"logoUrl":{"type":"string","format":"uri","description":"Optional HTTP or HTTPS PNG/JPG image URL for video, infographic, and slide_deck requests. Any source dimensions are accepted, but the image must be fully opaque and no larger than 5 MB; it is normalized to an opaque 200x50 PNG using the same rules as a project image. When supplied, it overrides the project logo for this request while project context and branding colors still apply. When omitted, the project logo and then the default logo are used."},"youtubeChannels":{"type":"array","items":{"type":"string"},"description":"YouTube channel IDs already connected to the account to use as sources"},"podcastEpisodeIds":{"type":"array","items":{"type":"string"},"description":"Completed audio request IDs to reuse as podcast episode sources (max 10)"},"text":{"type":"string","description":"Instructions or query for content generation"},"outputType":{"type":"string","enum":["audio","text","faq","study_guide","timeline","briefing_doc","quiz","video","infographic","slide_deck","datatable"],"description":"Type of output content to generate"},"duration":{"type":"string","enum":["short","default","long"],"description":"Duration preference for audio and slide deck generation. Ignored for video requests."},"format":{"type":"string","enum":["explainer","short","cinematic","text","html","pdf"],"description":"For `video`, accepted values are `explainer`, `short`, and `cinematic` (defaults to `explainer`). `cinematic` video requests cost 100 credits. For `briefing_doc`, accepted values are `text`, `html`, and `pdf` (defaults to `pdf`). Ignored for other output types."},"style":{"type":"string","description":"Style of the generated content. For audio/text, use one of: deep dive, brief, critique, debate. For video, any custom style text is accepted (defaults to classic when omitted).\n"},"introMusicUrl":{"type":"string","description":"HTTPS URL to optional intro music (.mp3, .wav, or .m4a) mixed at lower volume at the start of the podcast"},"includeCitations":{"type":"boolean","description":"Whether to include citations (PRO only)"},"ignorePaywalledResources":{"type":"boolean","description":"When true, continue processing even if some URL resources fail to import (paywall/restrictions). The request fails only if none of the provided resources are successfully imported."},"infographicOrientation":{"type":"string","enum":["landscape","portrait","square"],"description":"Infographic orientation (defaults to landscape)"},"infographicDetail":{"type":"string","enum":["concise","standard","detailed"],"description":"Infographic detail level (defaults to standard)"},"slideDeckFormat":{"type":"string","enum":["detailed","presenter"],"description":"Slide deck format (defaults to detailed). Length is controlled via the standard duration field (short, default, long). Slide deck prompt uses the main text field."},"quizDifficulty":{"type":"string","enum":["easy","medium","hard"],"description":"Difficulty level for quiz outputs (defaults to medium). Quiz prompt uses the main text field."},"callbackData":{"type":"string","maxLength":500,"description":"Optional data to include in webhooks (maximum 500 characters)"},"relatedId":{"type":"string","description":"Existing request ID to relate this request to (must belong to the same token)"},"notebookId":{"type":"string","description":"Owned Private Notebook ID. When present, generation uses that notebook's saved sources and its license's exact dedicated account, follows Private Notebooks capacity instead of content credits, and rejects additional request sources or generic topic/project inputs."},"language":{"type":"string","description":"Language for content generation"},"scheduledOn":{"type":"string","format":"date-time","description":"Schedule the content generation for a specific time"},"podcastId":{"type":"string","description":"Podcast show ID to associate this content with"},"episodeTitle":{"type":"string","description":"Optional episode title when attaching to a podcast show"},"title":{"type":"string","description":"Custom title to use for generated video outputs. When provided, overrides the automatically generated title."},"titlePrompt":{"type":"string","description":"Prompt to guide the generated video title"},"descriptionPrompt":{"type":"string","description":"Prompt to guide the generated video description"},"thumbnailImagePrompt":{"type":"string","description":"Prompt to control the generated thumbnail image for video outputs"},"introImagePrompt":{"type":"string","description":"Prompt to control the intro image for video outputs"},"voice1":{"type":"integer","description":"Primary custom voice id from /content/GetVoices. Use the numeric id value, not the voice name."},"voice2":{"type":"integer","description":"Secondary custom voice id from /content/GetVoices. Requires voice1."},"publishTargets":{"type":"array","description":"Targets to publish generated videos to (e.g., YouTube)","items":{"$ref":"#/components/schemas/PublishTarget"}},"templateMode":{"type":"object","description":"Create a reusable template instead of processing immediately","properties":{"type":{"type":"string","enum":["feed"]},"name":{"type":"string","description":"Optional display name for the template"}}},"isScheduled":{"type":"boolean","description":"Create a recurring schedule instead of a single request"},"dailyCount":{"type":"integer","minimum":1,"maximum":24,"description":"Number of times per day to run when isScheduled is true"},"scheduleEndDate":{"type":"string","format":"date-time","description":"Optional end date for recurring schedules (requires isScheduled true)"}}},"FeedSelection":{"type":"object","required":["feedId","feedItemIds"],"properties":{"feedId":{"type":"integer","description":"Identifier of the feed containing the cached items"},"feedItemIds":{"type":"array","items":{"type":"string"},"description":"Identifiers of cached posts or videos to include from that feed"}}},"PublishTarget":{"type":"object","properties":{"channel":{"type":"string","description":"Target channel for publishing (e.g., youtube)"},"youtubeAccountId":{"type":"string","nullable":true,"description":"Connected YouTube account ID to publish to"},"youtubePlaylistId":{"type":"string","nullable":true,"description":"Optional playlist ID to publish into"}}}}},"paths":{"/content/Create":{"post":{"summary":"Create new content","description":"Generate new content based on resources, topic, feed selections, researches, YouTube channels, or linked podcast episodes. Use video metadata fields (titlePrompt, descriptionPrompt, thumbnailImagePrompt, introImagePrompt, voices, publishTargets, format) when outputType is video. Video requests ignore the generic duration field if it is provided. Set isScheduled or templateMode to create recurring templates instead of immediate processing.","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentRequest"}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"oneOf":[{"type":"object","description":"Standard immediate request","properties":{"request_id":{"type":"string","description":"Unique ID for tracking the request"},"status":{"type":"integer","description":"Initial status code (0)"}}},{"type":"object","description":"Response when creating a recurring schedule (isScheduled = true)","properties":{"schedule_id":{"type":"string"},"request_id":{"type":"string"},"status":{"type":"integer"},"message":{"type":"string"},"dailyCount":{"type":"integer"},"endDate":{"type":"string","format":"date-time","nullable":true}}},{"type":"object","description":"Response when creating a reusable template (templateMode)","properties":{"template_request_id":{"type":"string"},"request_id":{"type":"string"},"status":{"type":"integer"},"template":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string","nullable":true}}}}}]}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Repurpose a completed request

> Creates a new request using the resources and parameters of a completed request, allowing a new output type and optional updated text.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"RepurposeRequest":{"type":"object","required":["requestId","outputType"],"properties":{"requestId":{"type":"string","description":"Identifier of the completed request to repurpose"},"outputType":{"type":"string","enum":["audio","video","infographic","slide_deck","datatable","quiz"],"description":"Output type for the new request"},"language":{"type":"string","description":"Optional language override for the new request (defaults to the original request language)"},"text":{"type":"string","description":"Optional text instructions that replace the original TEXT parameter"},"callbackData":{"type":"string","description":"Optional callback data to associate with the new request"},"duration":{"type":"string","enum":["short","default","long"],"description":"Duration preference for audio and slide deck repurpose requests. Ignored for video requests."},"infographicOrientation":{"type":"string","enum":["landscape","portrait","square"],"description":"Orientation when repurposing to an infographic"},"infographicDetail":{"type":"string","enum":["concise","standard","detailed"],"description":"Detail level when repurposing to an infographic"},"slideDeckFormat":{"type":"string","enum":["detailed","presenter"],"description":"Format when repurposing to a slide deck"},"quizDifficulty":{"type":"string","enum":["easy","medium","hard"],"description":"Difficulty level when repurposing to a quiz"},"title":{"type":"string","description":"Override video title when repurposing to video"},"titlePrompt":{"type":"string","description":"Prompt to guide the generated title when repurposing to video"},"descriptionPrompt":{"type":"string","description":"Prompt to guide the generated description when repurposing to video"},"format":{"type":"string","enum":["explainer","short","cinematic"],"description":"Video format (defaults to explainer). Only applies when outputType is video. `cinematic` costs 100 credits."},"style":{"type":"string","description":"Custom style text for video outputs"},"thumbnailImagePrompt":{"type":"string","description":"Prompt to control the generated thumbnail image for video outputs"},"introImagePrompt":{"type":"string","description":"Prompt to control the generated intro image for video outputs"},"avatarId":{"type":"integer","description":"Optional avatar identifier for explainer video generation. If omitted, inherits from the source request when available."},"audioLanguage":{"type":"string","description":"Optional audio language override for explainer video generation metadata. If omitted, inherits from the source request when available."},"textLanguage":{"type":"string","description":"Optional text language override for explainer video generation metadata. If omitted, inherits from the source request when available."},"backgroundImageUrl":{"type":"string","description":"Optional background image URL for explainer video generation metadata. If omitted, inherits from the source request when available."},"voiceId":{"type":"integer","description":"Optional voice id from /content/GetVoices for explainer video metadata. Use the numeric id value, not the voice name. If omitted, inherits from the source request when available."}}}}},"paths":{"/content/Repurpose":{"post":{"summary":"Repurpose a completed request","description":"Creates a new request using the resources and parameters of a completed request, allowing a new output type and optional updated text.","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepurposeRequest"}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","description":"Unique ID for tracking the new request"},"status":{"type":"integer","description":"Initial status code (0)"}}}}}},"400":{"description":"Invalid request or request not completed"},"401":{"description":"Unauthorized"},"404":{"description":"Original request not found"}}}}}}
```

## Check request status

> Get the status of a content generation request. A non-null \`error\_on\` or non-zero \`error\_code\` is a terminal failure; the numeric \`status\` may remain at its last processing stage, including 0.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Citation":{"type":"object","properties":{"text":{"type":"string","description":"Citation text"},"source":{"type":"string","description":"Source of the citation"},"page":{"type":"integer","description":"Page number for PDF sources"},"timeMs":{"type":"integer","description":"Timestamp in milliseconds for audio/video sources"}}}}},"paths":{"/content/Status/{id}":{"get":{"summary":"Check request status","description":"Get the status of a content generation request. A non-null `error_on` or non-zero `error_code` is a terminal failure; the numeric `status` may remain at its last processing stage, including 0.","tags":["Content"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"Request ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","description":"Request ID"},"audio_title":{"type":"string","description":"Title of the generated audio"},"status":{"type":"integer","description":"Status code (100 = completed)"},"audio_url":{"type":"string","description":"URL to the generated audio file"},"video_url":{"type":"string","description":"URL to the generated video file (if applicable)"},"image_url":{"type":"string","description":"URL to the generated image file (if applicable)"},"response_text":{"type":"string","description":"Generated text content"},"requested_on":{"type":"string","format":"date-time","description":"When the request was created"},"callback_data":{"type":"string","description":"User-provided callback data"},"updated_on":{"type":"string","format":"date-time","description":"When the request was last updated"},"request_type_id":{"type":"integer","description":"Type of request"},"error_code":{"type":"integer","description":"Error code (0 if no error)"},"citations":{"type":"array","items":{"$ref":"#/components/schemas/Citation"},"description":"Citations if requested"},"file_size":{"type":"integer","description":"Size of the generated file in bytes"},"audio_duration":{"type":"number","description":"Duration of the audio in seconds"},"share_url":{"type":"string","description":"Public sharing URL for the content"},"briefing_doc_url":{"type":"string","description":"Direct URL to the generated Briefing Doc PDF when output type is `briefing_doc`"},"document_format":{"type":"string","description":"Stored document format when output type is `briefing_doc`"},"document_content":{"type":"string","description":"Stored text or HTML content when output type is `briefing_doc`"},"document_url":{"type":"string","description":"Stored PDF URL when output type is `briefing_doc`"}}},{"type":"object","properties":{"id":{"type":"string","description":"Request ID"},"status":{"type":"integer","description":"Status code (0 = pending, other values indicate processing stages)"},"updated_on":{"type":"string","format":"date-time","description":"When the request was last updated"},"error_code":{"type":"integer","description":"Error code (0 if no error)"},"error_message":{"type":"string","description":"Error message if any"},"requested_on":{"type":"string","format":"date-time","description":"When the request was created"},"callback_data":{"type":"string","description":"User-provided callback data"}}}]}}}},"401":{"description":"Unauthorized"},"404":{"description":"Request not found"}}}}}}
```

## List content requests

> Get a list of content generation requests. Supports optional pagination.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/List":{"get":{"summary":"List content requests","description":"Get a list of content generation requests. Supports optional pagination.","tags":["Content"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"required":false,"description":"Page number for pagination (starts at 1). If not provided, returns all results."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"description":"Number of items per page (max 100, default 50 if page is specified)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"array","description":"Non-paginated response (when page and limit are not provided)","items":{"type":"object","properties":{"id":{"type":"string","description":"Request ID"},"requestTypeId":{"type":"integer","description":"Type of content request"},"status":{"type":"integer","description":"Current status code"},"requestedOn":{"type":"string","format":"date-time","description":"Request creation timestamp"},"audioTitle":{"type":"string","description":"Title of the generated audio (if available)"}}}},{"type":"object","description":"Paginated response (when page or limit are provided)","properties":{"requests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Request ID"},"requestTypeId":{"type":"integer","description":"Type of content request"},"status":{"type":"integer","description":"Current status code"},"requestedOn":{"type":"string","format":"date-time","description":"Request creation timestamp"},"audioTitle":{"type":"string","description":"Title of the generated audio (if available)"}}}},"totalCount":{"type":"integer","description":"Total number of requests"},"page":{"type":"integer","description":"Current page number"},"pageSize":{"type":"integer","description":"Number of items per page"},"totalPages":{"type":"integer","description":"Total number of pages"}}}]}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Get available voices

> List all available voices for audio generation

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/GetVoices":{"get":{"summary":"Get available voices","description":"List all available voices for audio generation","tags":["Content"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","description":"Numeric voice id to pass as voice1, voice2, or voiceId in voice-enabled requests"},"name":{"type":"string","description":"Voice name"},"clientId":{"type":"string","description":"ID of the client that owns this voice (for custom voices)"}}}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Get current client info

> Returns current client ID

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/Me":{"get":{"summary":"Get current client info","description":"Returns current client ID","tags":["Content"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"clientId":{"type":"string","description":"Current authenticated client ID"}}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Register webhook

> Register an HTTPS webhook URL for terminal request notifications. Callbacks are sent for both successes and failures; failure callbacks include \`error\_code\` and \`error\_message\`.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/Webhook":{"post":{"summary":"Register webhook","description":"Register an HTTPS webhook URL for terminal request notifications. Callbacks are sent for both successes and failures; failure callbacks include `error_code` and `error_message`.","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Webhook URL to register"}}}}}},"responses":{"200":{"description":"Webhook registered","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Webhook ID"},"url":{"type":"string","description":"Registered webhook URL"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Remove webhook

> Remove a registered webhook

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/RemoveWebhook":{"post":{"summary":"Remove webhook","description":"Remove a registered webhook","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"ID of the webhook to remove"}}}}}},"responses":{"200":{"description":"Webhook removed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the operation was successful"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Get webhooks

> List all registered webhooks

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/Webhooks":{"get":{"summary":"Get webhooks","description":"List all registered webhooks","tags":["Content"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Webhook ID"},"url":{"type":"string","description":"Registered webhook URL"}}}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Modify podcast

> Modify an existing podcast with new voices and background music

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/ModifyPodcast":{"post":{"summary":"Modify podcast","description":"Modify an existing podcast with new voices and background music","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["audioUrl","voice1","voice2"],"properties":{"audioUrl":{"type":"string","description":"URL to the audio file to modify"},"voice1":{"type":"integer","description":"Numeric id of first voice from /content/GetVoices"},"voice2":{"type":"integer","description":"Numeric id of second voice from /content/GetVoices"},"instructions":{"type":"string","description":"Additional instructions"},"backgroundMusicUrl":{"type":"string","description":"Optional URL to background music file"},"callbackData":{"type":"string","description":"Optional data for webhook callbacks"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","description":"Unique ID for tracking the request"},"status":{"type":"integer","description":"Initial status code (0)"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Separate speakers in audio

> Separate speakers in an audio file

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/SeparateSpeakersAudio":{"post":{"summary":"Separate speakers in audio","description":"Separate speakers in an audio file","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["audioUrl"],"properties":{"audioUrl":{"type":"string","description":"URL to the audio file"},"callbackData":{"type":"string","description":"Optional data for webhook callbacks"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","description":"Unique ID for tracking the request"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Clone voice

> Clone a voice from an audio file (PRO only). Accepts either a file upload or a URL.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/CloneVoice":{"post":{"summary":"Clone voice","description":"Clone a voice from an audio file (PRO only). Accepts either a file upload or a URL.","tags":["Content"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["name"],"properties":{"audioFile":{"type":"string","format":"binary","description":"MP3 audio file to upload (max 10MB). Cannot be used with audioUrl."},"name":{"type":"string","description":"Name for the cloned voice"}}}},"application/json":{"schema":{"type":"object","required":["audioUrl","name"],"properties":{"audioUrl":{"type":"string","description":"URL to the MP3 audio file for voice cloning. Cannot be used with audioFile upload."},"name":{"type":"string","description":"Name for the cloned voice"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","description":"Unique ID for tracking the request"},"status":{"type":"integer","description":"Initial status code (0)"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Get transcript

> Generate transcript from an audio file or episode. Accepts file upload, URL, or episode ID (only one at a time).

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/GetTranscript":{"post":{"summary":"Get transcript","description":"Generate transcript from an audio file or episode. Accepts file upload, URL, or episode ID (only one at a time).","tags":["Content"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"audioFile":{"type":"string","format":"binary","description":"MP3 or WAV audio file to upload (max 50MB). Cannot be used with audioUrl or episodeId."},"callbackData":{"type":"string","description":"Optional data for webhook callbacks"}}}},"application/json":{"schema":{"type":"object","oneOf":[{"required":["audioUrl"]},{"required":["episodeId"]}],"properties":{"audioUrl":{"type":"string","description":"URL to the audio file (.mp3 or .wav format). Cannot be used with audioFile or episodeId."},"episodeId":{"type":"string","description":"ID of an existing episode to transcribe. Cannot be used with audioFile or audioUrl."},"callbackData":{"type":"string","description":"Optional data for webhook callbacks"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","description":"Unique ID for tracking the request"},"status":{"type":"integer","description":"Initial status code (0)"}}}}}},"400":{"description":"Invalid request (missing parameters, both parameters provided, or invalid audio format)"},"401":{"description":"Unauthorized"}}}}}}
```

## Get transcript by episode ID

> Retrieve an existing transcript for a specific episode

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/GetTranscript/{episodeId}":{"get":{"summary":"Get transcript by episode ID","description":"Retrieve an existing transcript for a specific episode","tags":["Content"],"parameters":[{"in":"path","name":"episodeId","required":true,"schema":{"type":"string"},"description":"The ID of the episode to get the transcript for"}],"responses":{"200":{"description":"Transcript retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the operation was successful"},"episodeId":{"type":"string","description":"The episode ID that was requested"},"requestId":{"type":"string","description":"The original request ID used to generate this transcript"},"transcript":{"type":"string","description":"The transcript content (JSON string format)"},"createdOn":{"type":"string","format":"date-time","description":"When the transcript was created"}}}}}},"400":{"description":"Invalid request (missing episode ID)"},"401":{"description":"Unauthorized"},"404":{"description":"Transcript not found for the specified episode ID"},"500":{"description":"Internal server error"}}}}}}
```

## Create podcast from custom script

> Create a podcast using a custom script

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/CreatePodcastCustomScript":{"post":{"summary":"Create podcast from custom script","description":"Create a podcast using a custom script","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["script","voice1","voice2"],"properties":{"script":{"type":"string","description":"Script with SPEAKER_00/SPEAKER_01 prefixes"},"voice1":{"type":"integer","description":"Numeric id of first voice from /content/GetVoices (SPEAKER_00)"},"voice2":{"type":"integer","description":"Numeric id of second voice from /content/GetVoices (SPEAKER_01)"},"callbackData":{"type":"string","description":"Optional data for webhook callbacks"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","description":"Unique ID for tracking the request"},"status":{"type":"integer","description":"Initial status code (0)"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Create podcast with custom voices

> Create a podcast with specified voices based on resources, topic, or feeds. Either 'resources', 'topic', or 'feeds' must be provided.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/CreatePodcastCustomVoices":{"post":{"summary":"Create podcast with custom voices","description":"Create a podcast with specified voices based on resources, topic, or feeds. Either 'resources', 'topic', or 'feeds' must be provided.","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["voice1","voice2"],"properties":{"resources":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["text","youtube","website","pdf","file"]},"content":{"type":"string","description":"For type \"file\", provide an https URL or a file id returned by POST /files. For other types, provide the text or URL expected by that type."}}},"description":"Resources for content generation (required if topic or feeds are not provided)"},"topic":{"type":"string","description":"Topic for content generation (alternative to resources or feeds)"},"feeds":{"type":"array","items":{"type":"integer"},"description":"Array of feed IDs for content generation (alternative to resources or topic, max 10)"},"projects":{"type":"array","items":{"type":"string"},"description":"Array of project IDs to use as context for generation (max 10)"},"text":{"type":"string","description":"Instructions or query for content generation"},"voice1":{"type":"integer","description":"Numeric id of first voice from /content/GetVoices"},"voice2":{"type":"integer","description":"Numeric id of second voice from /content/GetVoices"},"duration":{"type":"string","enum":["short","long","default"],"description":"Duration preference for content generation"},"style":{"type":"string","enum":["deep dive","brief","critique","debate"],"description":"Style of podcast content (defaults to deep dive)"},"language":{"type":"string","description":"Optional language for the generated podcast (leave empty to use the default)"},"notebookId":{"type":"string","description":"Notebook ID for enterprise clients"},"callbackData":{"type":"string","description":"Optional data for webhook callbacks"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","description":"Unique ID for tracking the request"},"status":{"type":"integer","description":"Initial status code (0)"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Remove cloned voice

> Remove a cloned voice owned by the current user

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/RemoveVoice":{"post":{"summary":"Remove cloned voice","description":"Remove a cloned voice owned by the current user","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"integer","description":"ID of the voice to remove"}}}}}},"responses":{"200":{"description":"Voice removed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the operation was successful"},"message":{"type":"string","description":"Success message"}}}}}},"400":{"description":"Invalid request or missing voice ID"},"401":{"description":"Unauthorized"},"404":{"description":"Voice not found or cannot be deleted"}}}}}}
```

## Delete request

> Mark a content request as deleted

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/content/DeleteRequest":{"post":{"summary":"Delete request","description":"Mark a content request as deleted","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"ID of the request to delete"}}}}}},"responses":{"200":{"description":"Request deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the operation was successful"},"message":{"type":"string","description":"Success message"}}}}}},"400":{"description":"Invalid request or missing request ID"},"401":{"description":"Unauthorized"},"404":{"description":"Request not found or not owned by user"},"500":{"description":"Failed to delete request"}}}}}}
```

## Schedule multiple podcasts

> Create multiple podcasts at once, scheduled at intervals from a start time. Supports two modes - URLs mode (one podcast per episode, with each episode containing multiple URLs) or cached sources mode (feedSelections and/or youtubeChannels). Either 'urls' or (feedSelections/youtubeChannels + numberOfEpisodes) must be provided, but not both.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Content","description":"Content operations and usage information"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"FeedSelection":{"type":"object","required":["feedId","feedItemIds"],"properties":{"feedId":{"type":"integer","description":"Identifier of the feed containing the cached items"},"feedItemIds":{"type":"array","items":{"type":"string"},"description":"Identifiers of cached posts or videos to include from that feed"}}}}},"paths":{"/content/Schedule":{"post":{"summary":"Schedule multiple podcasts","description":"Create multiple podcasts at once, scheduled at intervals from a start time. Supports two modes - URLs mode (one podcast per episode, with each episode containing multiple URLs) or cached sources mode (feedSelections and/or youtubeChannels). Either 'urls' or (feedSelections/youtubeChannels + numberOfEpisodes) must be provided, but not both.","tags":["Content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["frequency"],"oneOf":[{"required":["urls"]},{"required":["feedSelections","numberOfEpisodes"]},{"required":["youtubeChannels","numberOfEpisodes"]}],"properties":{"urls":{"type":"array","items":{"type":"array","items":{"type":"string","format":"uri"}},"description":"Array of episodes, where each episode is an array of URLs to create a podcast from (URLs mode - cannot be used with feedSelections or youtubeChannels)"},"feedSelections":{"type":"array","description":"Cached feed items to include in scheduled episodes (cannot be used with urls)","items":{"$ref":"#/components/schemas/FeedSelection"}},"numberOfEpisodes":{"type":"integer","minimum":1,"maximum":100,"description":"Number of episodes to create (required when using feedSelections or youtubeChannels)"},"youtubeChannels":{"type":"array","items":{"type":"string"},"description":"Array of connected YouTube channel IDs to pull recent videos from (cannot be used with urls)"},"frequency":{"type":"integer","minimum":1,"description":"Frequency in minutes between scheduled podcasts"},"instructions":{"type":"string","maxLength":500,"description":"Optional instructions for podcast generation"},"brandUrl":{"type":"string","format":"uri","description":"Optional brand/service URL to include in each podcast (URLs mode only)"},"duration":{"type":"string","enum":["short","long","default"],"description":"Duration preference for podcasts"},"style":{"type":"string","enum":["deep dive","brief","critique","debate"],"description":"Style of podcast content"},"language":{"type":"string","description":"Language for podcast generation"},"podcastId":{"type":"string","description":"Podcast show ID to associate episodes with"},"episodeTitle":{"type":"string","description":"Optional episode title when associating to a podcast show"},"voice1":{"type":"integer","description":"Numeric id of first voice from /content/GetVoices (if provided, will use custom voices mode)"},"voice2":{"type":"integer","description":"Numeric id of second voice from /content/GetVoices (requires voice1)"},"startOn":{"type":"string","format":"date-time","description":"Start time for scheduling (defaults to current time, cannot be more than 24 hours in the past)"},"callbackData":{"type":"string","description":"Optional data for webhook callbacks"},"notebookId":{"type":"string","description":"Notebook ID for enterprise clients"}}}}}},"responses":{"200":{"description":"Podcasts scheduled successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the operation was successful"},"scheduled_requests":{"type":"array","items":{"oneOf":[{"type":"object","description":"Response for URLs mode","properties":{"request_id":{"type":"string","description":"ID of the scheduled request"},"urls":{"type":"array","items":{"type":"string"},"description":"Array of URLs this request was created from"},"scheduled_on":{"type":"string","format":"date-time","description":"When this request is scheduled to run"},"status":{"type":"integer","description":"Initial status (0)"}}},{"type":"object","description":"Response for feedSelections / YouTube mode","properties":{"request_id":{"type":"string","description":"ID of the scheduled request"},"feed_ids":{"type":"array","items":{"type":"integer"},"description":"Feed IDs used for this episode (if any)"},"feed_selections":{"type":"array","items":{"$ref":"#/components/schemas/FeedSelection"},"description":"Feed selections used for this episode"},"feed_items_per_episode":{"type":"integer","description":"Total cached items included across feeds for this episode"},"youtube_channel_ids":{"type":"array","items":{"type":"string"},"description":"YouTube channel IDs used for this episode"},"episode_number":{"type":"integer","description":"Episode number in the series"},"scheduled_on":{"type":"string","format":"date-time","description":"When this request is scheduled to run"},"status":{"type":"integer","description":"Initial status (0)"}}}]}},"total_created":{"type":"integer","description":"Total number of requests created"},"start_time":{"type":"string","format":"date-time","description":"Start time used for scheduling"},"frequency_minutes":{"type":"integer","description":"Frequency in minutes between requests"},"mode":{"type":"string","enum":["URLs","sources"],"description":"Mode used for scheduling"},"total_feeds_per_episode":{"type":"integer","description":"Number of feed groups per episode (sources mode only)"},"total_feed_items_per_episode":{"type":"integer","description":"Number of cached feed items per episode (sources mode only)"},"total_youtube_channels_per_episode":{"type":"integer","description":"Number of YouTube channels per episode (sources mode only)"},"total_urls":{"type":"integer","description":"Total number of URLs across all episodes (URLs mode only)"}}}}}},"400":{"description":"Invalid request parameters or insufficient credits"},"401":{"description":"Unauthorized"}}}}}}
```


# Video

Video generation and avatar operations

## Get available avatars

> List all available avatars for video generation

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Avatar":{"type":"object","properties":{"id":{"type":"string","description":"Avatar identifier"},"name":{"type":"string","description":"Avatar display name"},"gender":{"type":"string","enum":["M","F"],"description":"Avatar gender (M = Male, F = Female)"}}}}},"paths":{"/video/GetAvatars":{"get":{"summary":"Get available avatars","description":"List all available avatars for video generation","tags":["Video"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Avatar"}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Get shorts videos

> List all shorts videos for the authenticated user (includes pending, processing, completed, and failed)

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Short":{"type":"object","properties":{"id":{"type":"string","description":"Short video identifier"},"status":{"type":"integer","description":"Status code (0 = pending, 10-90 = processing, 100 = completed, -1 = failed)"},"requestedOn":{"type":"string","format":"date-time","description":"Request creation date"},"processingOn":{"type":"string","format":"date-time","description":"Processing start date"},"succeededOn":{"type":"string","format":"date-time","description":"Completion date"},"requestTypeId":{"type":"integer","description":"Request type ID (4 = Short)"},"callbackData":{"type":"string","description":"Custom callback data"},"audioUrl":{"type":"string","description":"URL to the audio used for the short"},"videoUrl":{"type":"string","description":"URL to the generated short video (when completed)"},"imageUrl":{"type":"string","description":"URL to the thumbnail image (when completed)"},"audioTitle":{"type":"string","description":"Title of the short video"},"responseText":{"type":"string","description":"Text content used in the short"},"errorOn":{"type":"string","format":"date-time","description":"Error occurrence date (if applicable)"},"errorMessage":{"type":"string","description":"Error message (if applicable)"}}}}},"paths":{"/video/GetShorts":{"get":{"summary":"Get shorts videos","description":"List all shorts videos for the authenticated user (includes pending, processing, completed, and failed)","tags":["Video"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Short"}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Create shorts

> Create short videos from audio content or feeds

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/video/CreateShorts":{"post":{"summary":"Create shorts","description":"Create short videos from audio content or feeds","tags":["Video"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["avatar1"],"properties":{"audioUrl":{"type":"string","description":"URL to the audio file to create shorts from (optional if feedIds provided)"},"feedIds":{"type":"array","items":{"type":"string"},"description":"Array of feed IDs to generate content from (optional if audioUrl provided)"},"prompt":{"type":"string","description":"Optional instructions for short creation"},"avatar1":{"type":"string","description":"ID of the first avatar to use"},"avatar2":{"type":"string","description":"Optional ID of the second avatar to use"},"subtitles":{"type":"boolean","description":"Optional boolean to include subtitles (default: true)"},"callbackData":{"type":"string","description":"Optional data to include in webhooks"},"scheduledOn":{"type":"string","format":"date-time","description":"Optional date/time to schedule the request for processing"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Request identifier"},"status":{"type":"integer","description":"Initial status code (0 = pending)"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Create shorts from text

> Create short videos from text content or feeds

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/video/CreateShortsFromContent":{"post":{"summary":"Create shorts from text","description":"Create short videos from text content or feeds","tags":["Video"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["avatar1"],"properties":{"content":{"type":"string","description":"Text content to create shorts from (optional if feedIds provided)"},"feedIds":{"type":"array","items":{"type":"string"},"description":"Array of feed IDs to generate content from (optional if content provided)"},"prompt":{"type":"string","description":"Optional instructions for short creation"},"avatar1":{"type":"string","description":"ID of the first avatar to use"},"avatar2":{"type":"string","description":"Optional ID of the second avatar to use"},"subtitles":{"type":"boolean","description":"Optional boolean to include subtitles (default: true)"},"callbackData":{"type":"string","description":"Optional data to include in webhooks"},"scheduledOn":{"type":"string","format":"date-time","description":"Optional date/time to schedule the request for processing"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Request identifier"},"status":{"type":"integer","description":"Initial status code (0 = pending)"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Create shorts from script

> Create short videos from a custom script with avatar dialogue or from feeds

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/video/CreateShortsFromScript":{"post":{"summary":"Create shorts from script","description":"Create short videos from a custom script with avatar dialogue or from feeds","tags":["Video"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"script":{"type":"array","description":"Array of dialogue entries with avatar IDs and text (optional if feedIds provided)","items":{"type":"object","required":["avatarId","text"],"properties":{"avatarId":{"type":"number","description":"ID of the avatar speaking this line"},"text":{"type":"string","description":"Text for the avatar to speak"}}}},"feedIds":{"type":"array","items":{"type":"string"},"description":"Array of feed IDs to generate content from (optional if script provided)"},"subtitles":{"type":"boolean","description":"Optional boolean to include subtitles (default: true)"},"callbackData":{"type":"string","description":"Optional data to include in webhooks"},"scheduledOn":{"type":"string","format":"date-time","description":"Optional date/time to schedule the request for processing"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Request identifier"},"status":{"type":"integer","description":"Initial status code (0 = pending)"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Create shorts from deep research

> Create short videos from the results of a completed deep research

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/video/CreateShortsFromDeepResearch":{"post":{"summary":"Create shorts from deep research","description":"Create short videos from the results of a completed deep research","tags":["Video"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["deepResearchId","avatar1"],"properties":{"deepResearchId":{"type":"string","description":"ID of the completed deep research to create shorts from"},"prompt":{"type":"string","description":"Optional instructions for short creation"},"avatar1":{"type":"string","description":"ID of the first avatar to use"},"avatar2":{"type":"string","description":"Optional ID of the second avatar to use"},"subtitles":{"type":"boolean","description":"Optional boolean to include subtitles (default: true)"},"callbackData":{"type":"string","description":"Optional data to include in webhooks"},"scheduledOn":{"type":"string","format":"date-time","description":"Optional date/time to schedule the request for processing"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Request identifier"},"status":{"type":"integer","description":"Initial status code (0 = pending)"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"404":{"description":"Deep research not found or not accessible"}}}}}}
```

## Create avatar

> Create a new talking head avatar from text or image

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/video/CreateAvatar":{"post":{"summary":"Create avatar","description":"Create a new talking head avatar from text or image","tags":["Video"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Name for the avatar"},"imageUrl":{"type":"string","description":"Optional URL to an image to use as the base for the avatar"},"prompt":{"type":"string","description":"Optional text prompt describing the avatar (used when imageUrl is not provided)"},"voiceId":{"type":"integer","description":"Optional numeric voice id from /content/GetVoices to use for the avatar"},"callbackData":{"type":"string","description":"Optional data to include in webhooks"},"scheduledOn":{"type":"string","format":"date-time","description":"Optional date/time to schedule the request for processing"}}}},"multipart/form-data":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Name for the avatar"},"imageFile":{"type":"string","format":"binary","description":"Image file to use as the base for the avatar (max 10MB, image files only)"},"prompt":{"type":"string","description":"Optional text prompt describing the avatar (used when imageFile is not provided)"},"voiceId":{"type":"integer","description":"Optional numeric voice id from /content/GetVoices to use for the avatar"},"callbackData":{"type":"string","description":"Optional data to include in webhooks"},"scheduledOn":{"type":"string","format":"date-time","description":"Optional date/time to schedule the request for processing"}}}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Request identifier"},"status":{"type":"integer","description":"Initial status code (0 = pending)"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}}}}}}
```

## Update avatar voice

> Update the voice assigned to an existing avatar

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/video/UpdateAvatarVoice":{"post":{"summary":"Update avatar voice","description":"Update the voice assigned to an existing avatar","tags":["Video"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["avatarId","voiceId"],"properties":{"avatarId":{"type":"integer","description":"ID of the avatar to update"},"voiceId":{"type":"integer","description":"Numeric voice id from /content/GetVoices to assign to the avatar"}}}}}},"responses":{"200":{"description":"Avatar voice updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Success status"},"message":{"type":"string","description":"Success message"}}}}}},"400":{"description":"Invalid request (missing or invalid parameters)"},"401":{"description":"Unauthorized"},"404":{"description":"Avatar not found or not accessible"},"500":{"description":"Failed to update avatar voice"}}}}}}
```

## Get explainer videos

> List all explainer videos for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/video/GetExplainerVideos":{"get":{"summary":"Get explainer videos","description":"List all explainer videos for the authenticated user","tags":["Video"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Video explainer identifier (matches request ID)"},"title":{"type":"string","description":"Title of the explainer video"},"description":{"type":"string","description":"Description of the explainer video"},"videoUrl":{"type":"string","description":"URL to the explainer video"},"fileSize":{"type":"integer","description":"Size of the video file in bytes"},"durationSeconds":{"type":"integer","description":"Duration of the video in seconds"},"shareUrl":{"type":"string","description":"Shareable public URL for the video"},"createdOn":{"type":"string","format":"date-time","description":"Creation date of the explainer video"},"requestedOn":{"type":"string","format":"date-time","description":"Request creation date"},"succeededOn":{"type":"string","format":"date-time","description":"Completion date"},"status":{"type":"integer","description":"Status code (100 = completed)"},"errorOn":{"type":"string","format":"date-time","description":"Error occurrence date (if applicable)"},"errorMessage":{"type":"string","description":"Error message (if applicable)"},"callbackData":{"type":"string","description":"Custom callback data"},"scheduledOn":{"type":"string","format":"date-time","description":"Scheduled processing time (if applicable)"}}}}}}},"401":{"description":"Unauthorized"},"500":{"description":"Internal server error"}}}}}}
```

## Transcribe an explainer video

> Submit a transcription job for an explainer video by ID

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/video/Transcribe":{"post":{"summary":"Transcribe an explainer video","description":"Submit a transcription job for an explainer video by ID","tags":["Video"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["videoId"],"properties":{"videoId":{"type":"string","description":"Explainer video ID (request ID)"}}}}}},"responses":{"200":{"description":"Transcription request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string"},"status":{"type":"integer"}}}}}},"400":{"description":"Invalid request (missing videoId)"},"401":{"description":"Unauthorized"},"404":{"description":"Explainer video not found or not ready"}}}}}}
```

## Get an explainer transcript

> Retrieve the transcript for a completed explainer video

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"ExplainerTranscript":{"type":"object","properties":{"videoId":{"type":"string","description":"Explainer video identifier (request ID)"},"createdOn":{"type":"string","format":"date-time","description":"Transcript creation timestamp"},"transcript":{"type":"array","items":{"$ref":"#/components/schemas/TranscriptLine"}}}},"TranscriptLine":{"type":"object","properties":{"text":{"type":"string","description":"Transcript line text"},"speaker":{"type":"string","description":"Speaker label"},"timestamp":{"type":"array","description":"Start/end time in seconds","items":{"type":"number"}}}}}},"paths":{"/video/Transcript/{videoId}":{"get":{"summary":"Get an explainer transcript","description":"Retrieve the transcript for a completed explainer video","tags":["Video"],"parameters":[{"in":"path","name":"videoId","required":true,"schema":{"type":"string"},"description":"Explainer video ID (request ID)"}],"responses":{"200":{"description":"Transcript retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExplainerTranscript"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Transcript not found for the specified explainer video"}}}}}}
```

## Generate branded intro image

> Generate the branded intro image used for explainer videos and download the PNG asset.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Video","description":"Video generation and avatar operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/video/GenerateIntroImage":{"get":{"summary":"Generate branded intro image","description":"Generate the branded intro image used for explainer videos and download the PNG asset.","tags":["Video"],"parameters":[{"in":"query","name":"title","required":true,"schema":{"type":"string"},"description":"Title text rendered on the intro image."},{"in":"query","name":"subtitle","required":false,"schema":{"type":"string"},"description":"Optional subtitle text displayed beneath the title."},{"in":"query","name":"logoUrl","required":false,"schema":{"type":"string"},"description":"Optional logo URL to render on the intro image."},{"in":"query","name":"heroImageUrl","required":false,"schema":{"type":"string"},"description":"Optional hero/background image URL composited into the intro artwork."}],"responses":{"200":{"description":"PNG image download containing the branded intro artwork.","headers":{"X-Intro-Image-Url":{"description":"Public URL of the uploaded intro image variant when available.","schema":{"type":"string"}},"X-Intro-Image-Size":{"description":"Size of the generated intro image in bytes.","schema":{"type":"integer"}}},"content":{"image/png":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Missing or invalid query parameters."},"401":{"description":"Unauthorized"},"500":{"description":"Error generating or uploading the intro image"}}}}}}
```


# Share

Public sharing operations without authentication

## Get a shared podcast

> Publicly retrieve a podcast by requestId and date string without requiring authentication

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Share","description":"Public sharing operations without authentication"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/share/podcast/{requestId}/{t}":{"get":{"summary":"Get a shared podcast","description":"Publicly retrieve a podcast by requestId and date string without requiring authentication","tags":["Share"],"parameters":[{"in":"path","name":"requestId","required":true,"schema":{"type":"string"},"description":"The ID of the podcast to retrieve"},{"in":"path","name":"t","required":true,"schema":{"type":"string"},"description":"Date in YYYYMMDD format to validate the request"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"integer"},"requestedOn":{"type":"string","format":"date-time"},"succeededOn":{"type":"string","format":"date-time"},"requestTypeId":{"type":"integer"},"audioTitle":{"type":"string"},"audioUrl":{"type":"string"},"responseText":{"type":"string"},"script":{"type":"string"},"voice1":{"type":"integer"},"voice2":{"type":"integer"},"language":{"type":"string"}}}}}},"400":{"description":"Bad Request - Invalid parameters"},"404":{"description":"Podcast not found"}}}}}}
```

## Get a shared video

> Publicly retrieve a generated video by requestId and date string without requiring authentication

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Share","description":"Public sharing operations without authentication"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/share/video/{requestId}/{t}":{"get":{"summary":"Get a shared video","description":"Publicly retrieve a generated video by requestId and date string without requiring authentication","tags":["Share"],"parameters":[{"in":"path","name":"requestId","required":true,"schema":{"type":"string"},"description":"The ID of the video to retrieve"},{"in":"path","name":"t","required":true,"schema":{"type":"string"},"description":"Date in YYYYMMDD format to validate the request"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"integer"},"requestedOn":{"type":"string","format":"date-time"},"succeededOn":{"type":"string","format":"date-time"},"videoTitle":{"type":"string"},"videoUrl":{"type":"string"},"imageUrl":{"type":"string"},"responseText":{"type":"string"},"language":{"type":"string"}}}}}},"400":{"description":"Bad Request - Invalid parameters"},"404":{"description":"Video not found"}}}}}}
```

## Get a shared infographic

> Publicly retrieve an infographic by requestId and date string without requiring authentication

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Share","description":"Public sharing operations without authentication"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/share/infographic/{requestId}/{t}":{"get":{"summary":"Get a shared infographic","description":"Publicly retrieve an infographic by requestId and date string without requiring authentication","tags":["Share"],"parameters":[{"in":"path","name":"requestId","required":true,"schema":{"type":"string"},"description":"The ID of the infographic to retrieve"},{"in":"path","name":"t","required":true,"schema":{"type":"string"},"description":"Date in YYYYMMDD format to validate the request"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"requestedOn":{"type":"string","format":"date-time"},"title":{"type":"string"},"imageUrl":{"type":"string"}}}}}},"400":{"description":"Bad Request - Invalid parameters"},"404":{"description":"Infographic not found"}}}}}}
```

## Get a shared slide deck

> Publicly retrieve a slide deck by requestId and date string without requiring authentication

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Share","description":"Public sharing operations without authentication"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/share/slide-deck/{requestId}/{t}":{"get":{"summary":"Get a shared slide deck","description":"Publicly retrieve a slide deck by requestId and date string without requiring authentication","tags":["Share"],"parameters":[{"in":"path","name":"requestId","required":true,"schema":{"type":"string"},"description":"The ID of the slide deck to retrieve"},{"in":"path","name":"t","required":true,"schema":{"type":"string"},"description":"Date in YYYYMMDD format to validate the request"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"requestedOn":{"type":"string","format":"date-time"},"title":{"type":"string"},"deckUrl":{"type":"string"}}}}}},"400":{"description":"Bad Request - Invalid parameters"},"404":{"description":"Slide deck not found"}}}}}}
```

## Get a shared quiz

> Publicly retrieve a quiz by requestId and date string without requiring authentication

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Share","description":"Public sharing operations without authentication"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/share/quiz/{requestId}/{t}":{"get":{"summary":"Get a shared quiz","description":"Publicly retrieve a quiz by requestId and date string without requiring authentication","tags":["Share"],"parameters":[{"in":"path","name":"requestId","required":true,"schema":{"type":"string"},"description":"The ID of the quiz to retrieve"},{"in":"path","name":"t","required":true,"schema":{"type":"string"},"description":"Date in YYYYMMDD format to validate the request"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"requestedOn":{"type":"string","format":"date-time"},"quizJson":{"type":"string"}}}}}},"400":{"description":"Bad Request - Invalid parameters"},"404":{"description":"Quiz not found"}}}}}}
```


# Podcast

Podcast operations and RSS feeds

## Get iTunes-compatible RSS feed for podcast distribution

> Generates a public RSS feed compatible with Spotify, Apple Music, and other podcast platforms.\
> This endpoint is designed for automated platform distribution - no authentication required.\
> \
> \*\*Platform Integration:\*\*\
> \- Submit this RSS URL to Spotify for Podcasters, Apple Podcasts Connect\
> \- Platforms automatically pull new episodes as they're added via API\
> \- Supports iTunes namespace for Apple Podcasts compatibility\
> \- Includes proper enclosure tags with audio URLs and metadata\
> \
> \*\*Automation Workflow:\*\*\
> 1\. Create podcast show → Get RSS URL from response\
> 2\. Submit RSS URL to podcast platforms (one-time setup)\
> 3\. Add episodes via API → Platforms automatically discover new content<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/podcast/rss/{podcastId}":{"get":{"summary":"Get iTunes-compatible RSS feed for podcast distribution","description":"Generates a public RSS feed compatible with Spotify, Apple Music, and other podcast platforms.\nThis endpoint is designed for automated platform distribution - no authentication required.\n\n**Platform Integration:**\n- Submit this RSS URL to Spotify for Podcasters, Apple Podcasts Connect\n- Platforms automatically pull new episodes as they're added via API\n- Supports iTunes namespace for Apple Podcasts compatibility\n- Includes proper enclosure tags with audio URLs and metadata\n\n**Automation Workflow:**\n1. Create podcast show → Get RSS URL from response\n2. Submit RSS URL to podcast platforms (one-time setup)\n3. Add episodes via API → Platforms automatically discover new content\n","tags":["Podcast"],"parameters":[{"in":"path","name":"podcastId","required":true,"schema":{"type":"string"},"description":"Podcast show ID to generate RSS feed for"}],"responses":{"200":{"description":"iTunes-compatible RSS XML feed ready for platform submission","content":{"application/xml":{"schema":{"type":"string","description":"RSS 2.0 XML feed with iTunes namespace extensions"}}}},"400":{"description":"Missing or invalid podcast ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error during RSS generation"}}}}}}
```

## Get all podcast shows for automated management

> Retrieves all podcast shows with their RSS URLs for platform distribution.\
> Each show includes its RSS feed URL for easy platform integration.\
> Supports optional pagination.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"PodcastShow":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the podcast show"},"name":{"type":"string","description":"Name of the podcast show (displayed on Spotify, Apple Music, etc.)"},"description":{"type":"string","description":"Description of the podcast show (used in platform listings)"},"author":{"type":"string","description":"Author/host name (displayed on podcast platforms)"},"link":{"type":"string","description":"Website link for the podcast show"},"email":{"type":"string","format":"email","description":"Owner email address (used in RSS feed and platform settings)"},"token":{"type":"string","description":"Client token for authentication"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedOn":{"type":"string","format":"date-time","description":"Last update timestamp"},"rssUrl":{"type":"string","description":"RSS feed URL for automated distribution to Spotify, Apple Music, and other podcast platforms"}}}}},"paths":{"/podcast/shows":{"get":{"summary":"Get all podcast shows for automated management","description":"Retrieves all podcast shows with their RSS URLs for platform distribution.\nEach show includes its RSS feed URL for easy platform integration.\nSupports optional pagination.\n","tags":["Podcast"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"required":false,"description":"Page number for pagination (starts at 1). If not provided, returns all results."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"description":"Number of items per page (max 100, default 50 if page is specified)"}],"responses":{"200":{"description":"List of podcast shows with RSS URLs for platform submission","content":{"application/json":{"schema":{"oneOf":[{"type":"array","description":"Non-paginated response (when page and limit are not provided)","items":{"$ref":"#/components/schemas/PodcastShow"}},{"type":"object","description":"Paginated response (when page or limit are provided)","properties":{"shows":{"type":"array","items":{"$ref":"#/components/schemas/PodcastShow"}},"totalCount":{"type":"integer","description":"Total number of podcast shows"},"page":{"type":"integer","description":"Current page number"},"pageSize":{"type":"integer","description":"Number of items per page"},"totalPages":{"type":"integer","description":"Total number of pages"}}}]}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error"}}}}}}
```

## Create a new podcast show for automated distribution

> Creates a new podcast show and returns the RSS URL for platform submission.\
> \
> \*\*Platform Setup Workflow:\*\*\
> 1\. Create show via this endpoint → Get RSS URL in response\
> 2\. Submit RSS URL to:\
> &#x20;  \- Spotify for Podcasters (<https://podcasters.spotify.com)\\>
> &#x20;  \- Apple Podcasts Connect (<https://podcastsconnect.apple.com)\\>
> &#x20;  \- Google Podcasts Manager\
> &#x20;  \- Other podcast platforms\
> 3\. Start adding episodes via API → Platforms automatically discover new content\
> \
> \*\*Required Metadata:\*\* All major podcast platforms require name, description, author, website link, and owner email for contact and verification purposes.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"CreatePodcastShowRequest":{"type":"object","required":["name","description","author","link","imageUrl","email"],"properties":{"name":{"type":"string","description":"Podcast show name (displayed on Spotify, Apple Music, etc.)"},"description":{"type":"string","description":"Show description for platform listings and RSS feed"},"author":{"type":"string","description":"Host/author name displayed on podcast platforms"},"link":{"type":"string","format":"uri","description":"Official website URL for the podcast show"},"imageUrl":{"type":"string","format":"uri","description":"URL of the podcast show image/artwork"},"email":{"type":"string","format":"email","description":"Owner email address for RSS feed and platform registration"},"language":{"type":"string","description":"Primary language for generated podcast episodes (defaults to English)"}}}}},"paths":{"/podcast/shows":{"post":{"summary":"Create a new podcast show for automated distribution","description":"Creates a new podcast show and returns the RSS URL for platform submission.\n\n**Platform Setup Workflow:**\n1. Create show via this endpoint → Get RSS URL in response\n2. Submit RSS URL to:\n   - Spotify for Podcasters (https://podcasters.spotify.com)\n   - Apple Podcasts Connect (https://podcastsconnect.apple.com)\n   - Google Podcasts Manager\n   - Other podcast platforms\n3. Start adding episodes via API → Platforms automatically discover new content\n\n**Required Metadata:** All major podcast platforms require name, description, author, website link, and owner email for contact and verification purposes.\n","tags":["Podcast"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePodcastShowRequest"}}}},"responses":{"201":{"description":"Podcast show created successfully with RSS URL for platform distribution","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"podcastId":{"type":"string","description":"Unique ID of the created podcast show"},"rssUrl":{"type":"string","description":"RSS feed URL to submit to Spotify, Apple Music, and other platforms"}}}}}},"400":{"description":"Bad request - Missing required fields for platform compatibility","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error during podcast creation"}}}}}}
```

## Create a new podcast show with image upload for automated distribution

> Creates a new podcast show with image upload and returns the RSS URL for platform submission.\
> This endpoint accepts multipart/form-data to allow direct image upload alongside podcast metadata.\
> \
> \*\*Platform Setup Workflow:\*\*\
> 1\. Create show via this endpoint → Get RSS URL in response\
> 2\. Submit RSS URL to:\
> &#x20;  \- Spotify for Podcasters (<https://podcasters.spotify.com)\\>
> &#x20;  \- Apple Podcasts Connect (<https://podcastsconnect.apple.com)\\>
> &#x20;  \- Google Podcasts Manager\
> &#x20;  \- Other podcast platforms\
> 3\. Start adding episodes via API → Platforms automatically discover new content\
> \
> \*\*Required Metadata:\*\* All major podcast platforms require name, description, author, website link, and owner email for contact and verification purposes.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/shows/with-image":{"post":{"summary":"Create a new podcast show with image upload for automated distribution","description":"Creates a new podcast show with image upload and returns the RSS URL for platform submission.\nThis endpoint accepts multipart/form-data to allow direct image upload alongside podcast metadata.\n\n**Platform Setup Workflow:**\n1. Create show via this endpoint → Get RSS URL in response\n2. Submit RSS URL to:\n   - Spotify for Podcasters (https://podcasters.spotify.com)\n   - Apple Podcasts Connect (https://podcastsconnect.apple.com)\n   - Google Podcasts Manager\n   - Other podcast platforms\n3. Start adding episodes via API → Platforms automatically discover new content\n\n**Required Metadata:** All major podcast platforms require name, description, author, website link, and owner email for contact and verification purposes.\n","tags":["Podcast"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["name","description","author","link","email","imageFile"],"properties":{"name":{"type":"string","description":"Podcast show name (displayed on Spotify, Apple Music, etc.)"},"description":{"type":"string","description":"Show description for platform listings and RSS feed"},"author":{"type":"string","description":"Host/author name displayed on podcast platforms"},"link":{"type":"string","format":"uri","description":"Official website URL for the podcast show"},"email":{"type":"string","format":"email","description":"Owner email address for RSS feed and platform registration"},"imageFile":{"type":"string","format":"binary","description":"Podcast show image/artwork file (JPG, PNG, etc.)"}}}}}},"responses":{"201":{"description":"Podcast show created successfully with RSS URL for platform distribution","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"podcastId":{"type":"string","description":"Unique ID of the created podcast show"},"rssUrl":{"type":"string","description":"RSS feed URL to submit to Spotify, Apple Music, and other platforms"},"imageUrl":{"type":"string","description":"URL of the uploaded podcast artwork image"}}}}}},"400":{"description":"Bad request - Missing required fields or invalid image file","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error during podcast creation"}}}}}}
```

## Get all podcast episodes for user (deprecated)

> Deprecated: this broad all-episodes endpoint is expensive for large accounts and will be removed later.\
> Use \`/podcast/episodes/unallocated\` for episodes not assigned to any show, or \`/podcast/shows/{podcastId}/episodes\` for show-specific episode lists.\
> \
> Retrieves all podcast episodes owned by the user, including:\
> \- Episodes assigned to one or more podcast shows (with podcast show IDs)\
> \- Orphaned episodes not yet assigned to any podcast show (with empty podcastShowIds array)\
> \
> Each episode includes an array of podcast show IDs it belongs to, supporting episodes that appear in multiple shows.\
> Useful for getting a comprehensive view of all published episodes and their distribution across shows.\
> Supports optional pagination.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"PodcastEpisode":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier for the episode"},"podcastId":{"type":"string","description":"ID of the podcast show this episode belongs to"},"requestId":{"type":"string","description":"ID of the client request that created the source audio content"},"title":{"type":"string","description":"Episode title (displayed on podcast platforms)"},"description":{"type":"string","description":"Episode description (displayed on podcast platforms)"},"audioTitle":{"type":"string","description":"Original title from the generated audio content"},"audioUrl":{"type":"string","description":"Direct URL to the episode audio file (MP3 format for platform compatibility)"},"requestedOn":{"type":"string","format":"date-time","description":"When the episode was requested/created"},"succeededOn":{"type":"string","format":"date-time","description":"When the episode processing completed successfully"},"scheduledOn":{"type":"string","format":"date-time","description":"When the episode is scheduled to be published (if scheduled)"},"fileSize":{"type":"integer","description":"Audio file size in bytes (required for RSS enclosure tag)"},"durationSeconds":{"type":"integer","description":"Episode duration in seconds (displayed on podcast platforms)"}}}}},"paths":{"/podcast/episodes":{"get":{"summary":"Get all podcast episodes for user (deprecated)","deprecated":true,"description":"Deprecated: this broad all-episodes endpoint is expensive for large accounts and will be removed later.\nUse `/podcast/episodes/unallocated` for episodes not assigned to any show, or `/podcast/shows/{podcastId}/episodes` for show-specific episode lists.\n\nRetrieves all podcast episodes owned by the user, including:\n- Episodes assigned to one or more podcast shows (with podcast show IDs)\n- Orphaned episodes not yet assigned to any podcast show (with empty podcastShowIds array)\n\nEach episode includes an array of podcast show IDs it belongs to, supporting episodes that appear in multiple shows.\nUseful for getting a comprehensive view of all published episodes and their distribution across shows.\nSupports optional pagination.\n","tags":["Podcast"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"required":false,"description":"Page number for pagination (starts at 1). If not provided, returns all results."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"description":"Number of items per page (max 100, default 50 if page is specified)"}],"responses":{"200":{"description":"List of all episodes with platform-ready metadata and associated podcast show IDs","content":{"application/json":{"schema":{"oneOf":[{"type":"array","description":"Non-paginated response (when page and limit are not provided)","items":{"allOf":[{"$ref":"#/components/schemas/PodcastEpisode"},{"type":"object","properties":{"podcastShowIds":{"type":"array","description":"Array of podcast show IDs this episode belongs to (empty for orphaned episodes)","items":{"type":"string"}}}}]}},{"type":"object","description":"Paginated response (when page or limit are provided)","properties":{"episodes":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/PodcastEpisode"},{"type":"object","properties":{"podcastShowIds":{"type":"array","description":"Array of podcast show IDs this episode belongs to (empty for orphaned episodes)","items":{"type":"string"}}}}]}},"totalCount":{"type":"integer","description":"Total number of episodes"},"page":{"type":"integer","description":"Current page number"},"pageSize":{"type":"integer","description":"Number of items per page"},"totalPages":{"type":"integer","description":"Total number of pages"}}}]}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error"}}}}}}
```

## Get unallocated podcast episodes for user

> Retrieves generated audio episodes that are not assigned to any podcast show.\
> This is the preferred paginated endpoint for the \`/podcasts/shows/unallocated\` app screen.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"PodcastEpisode":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier for the episode"},"podcastId":{"type":"string","description":"ID of the podcast show this episode belongs to"},"requestId":{"type":"string","description":"ID of the client request that created the source audio content"},"title":{"type":"string","description":"Episode title (displayed on podcast platforms)"},"description":{"type":"string","description":"Episode description (displayed on podcast platforms)"},"audioTitle":{"type":"string","description":"Original title from the generated audio content"},"audioUrl":{"type":"string","description":"Direct URL to the episode audio file (MP3 format for platform compatibility)"},"requestedOn":{"type":"string","format":"date-time","description":"When the episode was requested/created"},"succeededOn":{"type":"string","format":"date-time","description":"When the episode processing completed successfully"},"scheduledOn":{"type":"string","format":"date-time","description":"When the episode is scheduled to be published (if scheduled)"},"fileSize":{"type":"integer","description":"Audio file size in bytes (required for RSS enclosure tag)"},"durationSeconds":{"type":"integer","description":"Episode duration in seconds (displayed on podcast platforms)"}}}}},"paths":{"/podcast/episodes/unallocated":{"get":{"summary":"Get unallocated podcast episodes for user","description":"Retrieves generated audio episodes that are not assigned to any podcast show.\nThis is the preferred paginated endpoint for the `/podcasts/shows/unallocated` app screen.\n","tags":["Podcast"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"required":false,"description":"Page number for pagination (starts at 1)."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"description":"Number of items per page (max 100, default 50)."}],"responses":{"200":{"description":"Paginated list of unallocated podcast episodes.","content":{"application/json":{"schema":{"type":"object","properties":{"episodes":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/PodcastEpisode"},{"type":"object","properties":{"podcastShowIds":{"type":"array","description":"Always empty for unallocated episodes.","items":{"type":"string"}}}}]}},"totalCount":{"type":"integer","description":"Total number of unallocated episodes."},"page":{"type":"integer","description":"Current page number."},"pageSize":{"type":"integer","description":"Number of items per page."},"totalPages":{"type":"integer","description":"Total number of pages."},"draftEpisodes":{"type":"array","description":"Always empty for this endpoint.","items":{"type":"object"}}}}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error"}}}}}}
```

## Get all episodes for automated podcast management

> Retrieves all episodes for a specific podcast show.\
> Each episode includes an array of podcast show IDs it belongs to (including the specified one and any others).\
> Useful for monitoring automated podcast publishing and episode management.\
> Supports optional pagination.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"PodcastEpisode":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier for the episode"},"podcastId":{"type":"string","description":"ID of the podcast show this episode belongs to"},"requestId":{"type":"string","description":"ID of the client request that created the source audio content"},"title":{"type":"string","description":"Episode title (displayed on podcast platforms)"},"description":{"type":"string","description":"Episode description (displayed on podcast platforms)"},"audioTitle":{"type":"string","description":"Original title from the generated audio content"},"audioUrl":{"type":"string","description":"Direct URL to the episode audio file (MP3 format for platform compatibility)"},"requestedOn":{"type":"string","format":"date-time","description":"When the episode was requested/created"},"succeededOn":{"type":"string","format":"date-time","description":"When the episode processing completed successfully"},"scheduledOn":{"type":"string","format":"date-time","description":"When the episode is scheduled to be published (if scheduled)"},"fileSize":{"type":"integer","description":"Audio file size in bytes (required for RSS enclosure tag)"},"durationSeconds":{"type":"integer","description":"Episode duration in seconds (displayed on podcast platforms)"}}}}},"paths":{"/podcast/shows/{podcastId}/episodes":{"get":{"summary":"Get all episodes for automated podcast management","description":"Retrieves all episodes for a specific podcast show.\nEach episode includes an array of podcast show IDs it belongs to (including the specified one and any others).\nUseful for monitoring automated podcast publishing and episode management.\nSupports optional pagination.\n","tags":["Podcast"],"parameters":[{"in":"path","name":"podcastId","required":true,"schema":{"type":"string"},"description":"The podcast show ID"},{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"required":false,"description":"Page number for pagination (starts at 1). If not provided, returns all results."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"description":"Number of items per page (max 100, default 50 if page is specified)"}],"responses":{"200":{"description":"List of episodes with platform-ready metadata and associated podcast show IDs","content":{"application/json":{"schema":{"oneOf":[{"type":"array","description":"Non-paginated response (when page and limit are not provided)","items":{"allOf":[{"$ref":"#/components/schemas/PodcastEpisode"},{"type":"object","properties":{"podcastShowIds":{"type":"array","description":"Array of podcast show IDs this episode belongs to","items":{"type":"string"}}}}]}},{"type":"object","description":"Paginated response (when page or limit are provided)","properties":{"episodes":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/PodcastEpisode"},{"type":"object","properties":{"podcastShowIds":{"type":"array","description":"Array of podcast show IDs this episode belongs to","items":{"type":"string"}}}}]}},"totalCount":{"type":"integer","description":"Total number of episodes for this podcast show"},"page":{"type":"integer","description":"Current page number"},"pageSize":{"type":"integer","description":"Number of items per page"},"totalPages":{"type":"integer","description":"Total number of pages"}}}]}}}},"400":{"description":"Bad request - Invalid podcast ID"},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error"}}}}}}
```

## Add episode to podcast for automated distribution

> Converts existing audio content into a podcast episode for automated platform distribution.\
> \
> \*\*Automation Workflow:\*\*\
> 1\. Generate audio content via content API → Get requestId\
> 2\. Add episode via this endpoint → Links audio to podcast show\
> 3\. RSS feed automatically updates with new episode\
> 4\. Spotify, Apple Music, etc. automatically discover and publish new episode\
> \
> \*\*Content Linking:\*\* Uses requestId to link existing audio content, enabling seamless\
> conversion of any generated audio into podcast episodes without file uploads.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/shows/{podcastId}/episodes":{"post":{"summary":"Add episode to podcast for automated distribution","description":"Converts existing audio content into a podcast episode for automated platform distribution.\n\n**Automation Workflow:**\n1. Generate audio content via content API → Get requestId\n2. Add episode via this endpoint → Links audio to podcast show\n3. RSS feed automatically updates with new episode\n4. Spotify, Apple Music, etc. automatically discover and publish new episode\n\n**Content Linking:** Uses requestId to link existing audio content, enabling seamless\nconversion of any generated audio into podcast episodes without file uploads.\n","tags":["Podcast"],"parameters":[{"in":"path","name":"podcastId","required":true,"schema":{"type":"string"},"description":"The podcast show ID to add episode to"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string","description":"ID of existing audio content to convert into podcast episode"},"title":{"type":"string","description":"Custom episode title (optional - defaults to original audio title)"},"description":{"type":"string","description":"Custom episode description (optional - defaults to original audio title)"}}}}}},"responses":{"201":{"description":"Episode added successfully - will appear on podcast platforms automatically","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"episodeId":{"type":"integer","description":"ID of the created episode"},"message":{"type":"string"}}}}}},"400":{"description":"Bad request - Missing required fields or invalid IDs","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error during episode creation"}}}}}}
```

## Remove episode from automated podcast distribution

> Removes an episode from the podcast show and RSS feed.\
> The episode will be automatically removed from podcast platforms on their next RSS feed refresh.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/episodes/remove":{"post":{"summary":"Remove episode from automated podcast distribution","description":"Removes an episode from the podcast show and RSS feed.\nThe episode will be automatically removed from podcast platforms on their next RSS feed refresh.\n","tags":["Podcast"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["episodeId"],"properties":{"episodeId":{"type":"integer","description":"The episode ID to remove from podcast distribution"}}}}}},"responses":{"200":{"description":"Episode removed successfully - will be removed from platforms automatically","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Bad request - Missing or invalid episode ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"404":{"description":"Episode not found or cannot be deleted"},"500":{"description":"Internal server error during episode removal"}}}}}}
```

## Update podcast episode title and description

> Updates the title and description of a specific podcast episode.\
> The episode must belong to a podcast owned by the authenticated user.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/episodes/{episodeId}":{"post":{"summary":"Update podcast episode title and description","description":"Updates the title and description of a specific podcast episode.\nThe episode must belong to a podcast owned by the authenticated user.\n","tags":["Podcast"],"parameters":[{"in":"path","name":"episodeId","required":true,"schema":{"type":"integer"},"description":"The ID of the episode to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","description"],"properties":{"title":{"type":"string","description":"New episode title"},"description":{"type":"string","description":"New episode description"}}}}}},"responses":{"200":{"description":"Episode updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Bad request - Missing required fields or invalid episode ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"404":{"description":"Episode not found or cannot be updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error during episode update"}}}}}}
```

## Import podcast from RSS feed URL

> Imports an entire podcast show and its episodes from an existing RSS feed URL.\
> This is perfect for migrating podcasts from other platforms (Buzzsprout, Anchor, Podbean, etc.) to AutoContent API.\
> \
> \*\*Features:\*\*\
> \- Preserves ALL RSS metadata (language, copyright, categories, season/episode numbers, etc.)\
> \- Smart duplicate detection using GUIDs\
> \- Automatically imports and stores podcast artwork\
> \- Updates existing podcasts if they already exist\
> \- Generates new RSS feed URL that maintains all original metadata\
> \
> \*\*Migration Workflow:\*\*\
> 1\. Import your existing podcast from any platform using this endpoint\
> 2\. All metadata is preserved (language, categories, episode numbers, etc.)\
> 3\. Get a new RSS URL that you can submit to Spotify, Apple Podcasts, etc.\
> 4\. Your podcast continues seamlessly with all historical data intact<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/import-rss":{"post":{"summary":"Import podcast from RSS feed URL","description":"Imports an entire podcast show and its episodes from an existing RSS feed URL.\nThis is perfect for migrating podcasts from other platforms (Buzzsprout, Anchor, Podbean, etc.) to AutoContent API.\n\n**Features:**\n- Preserves ALL RSS metadata (language, copyright, categories, season/episode numbers, etc.)\n- Smart duplicate detection using GUIDs\n- Automatically imports and stores podcast artwork\n- Updates existing podcasts if they already exist\n- Generates new RSS feed URL that maintains all original metadata\n\n**Migration Workflow:**\n1. Import your existing podcast from any platform using this endpoint\n2. All metadata is preserved (language, categories, episode numbers, etc.)\n3. Get a new RSS URL that you can submit to Spotify, Apple Podcasts, etc.\n4. Your podcast continues seamlessly with all historical data intact\n","tags":["Podcast"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rssUrl"],"properties":{"rssUrl":{"type":"string","format":"uri","description":"The RSS feed URL to import from (must end with .rss or contain 'rss' or 'feed')"},"email":{"type":"string","format":"email","description":"Optional owner email override when the source RSS feed does not include itunes:owner email."}}}}}},"responses":{"200":{"description":"Podcast imported successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"podcastId":{"type":"string","description":"The ID of the imported/updated podcast show"},"rssUrl":{"type":"string","description":"Your new RSS feed URL for distribution to podcast platforms"}}}}}},"400":{"description":"Bad request - Invalid or missing RSS URL","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error during import","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```

## Remove podcast from distribution

> Endpoint for removing individual podcast episodes or shows.\
> \
> \*\*Note:\*\* This marks content as deleted rather than physically removing it,\
> allowing for potential recovery and maintaining referential integrity.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/remove":{"post":{"summary":"Remove podcast from distribution","description":"Endpoint for removing individual podcast episodes or shows.\n\n**Note:** This marks content as deleted rather than physically removing it,\nallowing for potential recovery and maintaining referential integrity.\n","tags":["Podcast"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"The podcast or episode ID to mark as deleted"}}}}}},"responses":{"200":{"description":"Podcast marked as deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Bad request - Missing podcast id","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"404":{"description":"Podcast not found or cannot be deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error during podcast removal"}}}}}}
```

## Download all podcast episodes as CSV

> Downloads all episodes for the authenticated user as a CSV file.\
> The CSV includes: id, audioUrl, title, and requestedOn fields.\
> Useful for data export, analysis, or backup purposes.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/episodes/csv":{"get":{"summary":"Download all podcast episodes as CSV","description":"Downloads all episodes for the authenticated user as a CSV file.\nThe CSV includes: id, audioUrl, title, and requestedOn fields.\nUseful for data export, analysis, or backup purposes.\n","tags":["Podcast"],"responses":{"200":{"description":"CSV file containing all podcast episodes","content":{"text/csv":{"schema":{"type":"string"}}},"headers":{"Content-Disposition":{"schema":{"type":"string"}},"Content-Type":{"schema":{"type":"string"}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error during CSV generation"}}}}}}
```

## Download podcast show episodes as CSV

> Downloads all episodes for a specific podcast show as a CSV file.\
> The CSV includes: id, audioUrl, title, and requestedOn fields.\
> Useful for exporting podcast show data for analysis or migration.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/shows/{podcastId}/episodes/csv":{"get":{"summary":"Download podcast show episodes as CSV","description":"Downloads all episodes for a specific podcast show as a CSV file.\nThe CSV includes: id, audioUrl, title, and requestedOn fields.\nUseful for exporting podcast show data for analysis or migration.\n","tags":["Podcast"],"parameters":[{"in":"path","name":"podcastId","required":true,"schema":{"type":"string"},"description":"The podcast show ID"}],"responses":{"200":{"description":"CSV file containing podcast show episodes","content":{"text/csv":{"schema":{"type":"string"}}},"headers":{"Content-Disposition":{"schema":{"type":"string"}},"Content-Type":{"schema":{"type":"string"}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error during CSV generation"}}}}}}
```

## Download all podcast episode audio files as a ZIP archive

> Streams a ZIP archive containing audio files for every episode owned by the authenticated user.\
> Only episodes with a valid \`audioUrl\` are included in the archive.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/episodes/audio-zip":{"get":{"summary":"Download all podcast episode audio files as a ZIP archive","description":"Streams a ZIP archive containing audio files for every episode owned by the authenticated user.\nOnly episodes with a valid `audioUrl` are included in the archive.\n","tags":["Podcast"],"responses":{"200":{"description":"ZIP archive containing all available episode audio files","headers":{"Content-Disposition":{"schema":{"type":"string"}},"Content-Type":{"schema":{"type":"string"}}}},"401":{"description":"Unauthorized - valid API token required"},"404":{"description":"No downloadable audio files were found"},"500":{"description":"Internal server error while building the audio archive"}}}}}}
```

## Download podcast show episode audio files as a ZIP archive

> Streams a ZIP archive with audio files for the specified podcast show. Only episodes\
> containing a valid \`audioUrl\` are included. If no files can be gathered, a 404 is returned.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/podcast/shows/{podcastId}/episodes/audio-zip":{"get":{"summary":"Download podcast show episode audio files as a ZIP archive","description":"Streams a ZIP archive with audio files for the specified podcast show. Only episodes\ncontaining a valid `audioUrl` are included. If no files can be gathered, a 404 is returned.\n","tags":["Podcast"],"parameters":[{"in":"path","name":"podcastId","required":true,"schema":{"type":"string"},"description":"The podcast show ID"}],"responses":{"200":{"description":"ZIP archive containing the show's available episode audio files","headers":{"Content-Disposition":{"schema":{"type":"string"}},"Content-Type":{"schema":{"type":"string"}}}},"401":{"description":"Unauthorized - valid API token required"},"404":{"description":"No downloadable audio files were found for the show"},"500":{"description":"Internal server error while building the audio archive"}}}}}}
```

## Generate podcast ideas (public, origin-restricted)

> Returns 3–8 podcast ideas. Each idea includes a podcast name, description,\
> exactly four episode titles, and AI-estimated 0–100 scores for questionComplexity,\
> topicalDepth, searchVolumeConversational, and contentFreshness.\
> No JWT required, but the request must come from an allowlisted Origin\
> (autocontentapi.com / app.autocontentapi.com / localhost) OR carry a valid\
> \`X-Free-Tools-Secret\` header (used by the Next.js proxy). Other callers\
> receive 403. Limits: 2 requests per IP per 24h, 30 total per 24h,\
> 2 concurrent per IP.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Podcast","description":"Podcast operations and RSS feeds"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/podcast/ideas":{"post":{"summary":"Generate podcast ideas (public, origin-restricted)","description":"Returns 3–8 podcast ideas. Each idea includes a podcast name, description,\nexactly four episode titles, and AI-estimated 0–100 scores for questionComplexity,\ntopicalDepth, searchVolumeConversational, and contentFreshness.\nNo JWT required, but the request must come from an allowlisted Origin\n(autocontentapi.com / app.autocontentapi.com / localhost) OR carry a valid\n`X-Free-Tools-Secret` header (used by the Next.js proxy). Other callers\nreceive 403. Limits: 2 requests per IP per 24h, 30 total per 24h,\n2 concurrent per IP.\n","tags":["Podcast"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","nullable":true,"description":"Optional topic to tailor podcast ideas. If omitted or null, the AI will propose topics."}}}}}},"responses":{"200":{"description":"Structured list of podcast ideas","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"requestId":{"type":"string"},"ideas":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"episodes":{"type":"array","items":{"type":"string"},"minItems":4,"maxItems":4},"stats":{"type":"object","properties":{"questionComplexity":{"type":"integer","minimum":0,"maximum":100},"topicalDepth":{"type":"integer","minimum":0,"maximum":100},"searchVolumeConversational":{"type":"integer","minimum":0,"maximum":100},"contentFreshness":{"type":"integer","minimum":0,"maximum":100}}}}}}}}}}},"429":{"description":"Rate limit exceeded (10/day) or too many concurrent requests (2/IP)"},"500":{"description":"Internal server error"}}}}}}
```


# Projects

Project context management for content generation

## Get all projects for the authenticated user

> Retrieves all active projects owned by the authenticated user.\
> Projects are returned in descending order by last update time.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Projects","description":"Project context management for content generation"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Project":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the project (GUID)"},"name":{"type":"string","description":"Name of the project"},"description":{"type":"string","description":"Detailed description of the project"},"url":{"type":"string","description":"Optional URL associated with the project"},"token":{"type":"string","description":"Client token (owner of the project)"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedOn":{"type":"string","format":"date-time","description":"Last update timestamp"},"active":{"type":"boolean","description":"Whether the project is active"},"imageUrl":{"type":"string","format":"uri","description":"Optional URL of the 200x50 brand image associated with the project"},"textColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"backgroundColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"brandColor":{"type":"string","nullable":true,"description":"Primary branding accent color applied to overlay shapes when branding is configured"},"accentColor":{"type":"string","nullable":true,"description":"Secondary accent color applied to overlay highlights and subtitles when branding is configured"}}}}},"paths":{"/projects":{"get":{"summary":"Get all projects for the authenticated user","description":"Retrieves all active projects owned by the authenticated user.\nProjects are returned in descending order by last update time.\n","tags":["Projects"],"responses":{"200":{"description":"List of user's projects","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error"}}}}}}
```

## Create a new project

> Creates a new project for the authenticated user.\
> Projects can be referenced when generating tweets/threads to provide context.\
> \
> If a URL is provided without a description, the API will:\
> 1\. Fetch the website content\
> 2\. Use AI to generate a comprehensive project description in markdown format\
> \
> Either description or url must be provided.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Projects","description":"Project context management for content generation"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"CreateProjectRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Name of the project (max 200 characters)"},"description":{"type":"string","description":"Detailed description of the project. Either description or url must be provided."},"url":{"type":"string","description":"Optional URL to fetch website content for auto-generating description. If provided without a description, AI will generate one."},"imageData":{"type":"string","description":"Optional base64 encoded PNG/JPG representing the project's brand image. The source image must be fully opaque; images containing any fully or partially transparent pixels are rejected. Any dimensions are accepted and the API resizes the image to 200x50 before storing the hosted copy as `imageUrl`."},"imageUrl":{"type":"string","format":"uri","description":"Optional HTTP/HTTPS URL to an existing PNG or JPG brand image. The source image must be fully opaque; images containing any fully or partially transparent pixels are rejected. The API downloads the source, resizes it to 200x50, and hosts the optimized copy. Cannot be combined with `imageData`."},"textColor":{"type":"string","description":"Optional hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"backgroundColor":{"type":"string","description":"Optional hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"brandColor":{"type":"string","description":"Optional primary accent hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"accentColor":{"type":"string","description":"Optional secondary accent hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"}}},"Project":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the project (GUID)"},"name":{"type":"string","description":"Name of the project"},"description":{"type":"string","description":"Detailed description of the project"},"url":{"type":"string","description":"Optional URL associated with the project"},"token":{"type":"string","description":"Client token (owner of the project)"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedOn":{"type":"string","format":"date-time","description":"Last update timestamp"},"active":{"type":"boolean","description":"Whether the project is active"},"imageUrl":{"type":"string","format":"uri","description":"Optional URL of the 200x50 brand image associated with the project"},"textColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"backgroundColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"brandColor":{"type":"string","nullable":true,"description":"Primary branding accent color applied to overlay shapes when branding is configured"},"accentColor":{"type":"string","nullable":true,"description":"Secondary accent color applied to overlay highlights and subtitles when branding is configured"}}}}},"paths":{"/projects":{"post":{"summary":"Create a new project","description":"Creates a new project for the authenticated user.\nProjects can be referenced when generating tweets/threads to provide context.\n\nIf a URL is provided without a description, the API will:\n1. Fetch the website content\n2. Use AI to generate a comprehensive project description in markdown format\n\nEither description or url must be provided.\n","tags":["Projects"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}}},"responses":{"201":{"description":"Project created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"project":{"$ref":"#/components/schemas/Project"}}}}}},"400":{"description":"Bad request - Missing required fields or validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error"}}}}}}
```

## Get a specific project by ID

> Retrieves a specific project by its ID.\
> Only the project owner can access their projects.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Projects","description":"Project context management for content generation"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Project":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the project (GUID)"},"name":{"type":"string","description":"Name of the project"},"description":{"type":"string","description":"Detailed description of the project"},"url":{"type":"string","description":"Optional URL associated with the project"},"token":{"type":"string","description":"Client token (owner of the project)"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedOn":{"type":"string","format":"date-time","description":"Last update timestamp"},"active":{"type":"boolean","description":"Whether the project is active"},"imageUrl":{"type":"string","format":"uri","description":"Optional URL of the 200x50 brand image associated with the project"},"textColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"backgroundColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"brandColor":{"type":"string","nullable":true,"description":"Primary branding accent color applied to overlay shapes when branding is configured"},"accentColor":{"type":"string","nullable":true,"description":"Secondary accent color applied to overlay highlights and subtitles when branding is configured"}}}}},"paths":{"/projects/{id}":{"get":{"summary":"Get a specific project by ID","description":"Retrieves a specific project by its ID.\nOnly the project owner can access their projects.\n","tags":["Projects"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"Project ID (GUID)"}],"responses":{"200":{"description":"Project details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"Bad request - Missing project ID"},"401":{"description":"Unauthorized - valid API token required"},"404":{"description":"Project not found"},"500":{"description":"Internal server error"}}}}}}
```

## Update a project

> Updates an existing project's name and description.\
> Only the project owner can update their projects.\
> \
> If a URL is provided without a description, the API will:\
> 1\. Fetch the website content\
> 2\. Use AI to generate a comprehensive project description in markdown format\
> \
> Either description or url must be provided.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Projects","description":"Project context management for content generation"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"UpdateProjectRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Updated name of the project (max 200 characters)"},"description":{"type":"string","description":"Updated description of the project. Either description or url must be provided."},"url":{"type":"string","description":"Optional URL to fetch website content for auto-generating description. If provided without a description, AI will generate one."},"imageData":{"type":"string","nullable":true,"description":"Optional base64 encoded PNG/JPG. Provide `null` to remove the current brand image. The source image must be fully opaque; images containing any fully or partially transparent pixels are rejected. Any size is accepted and will be resized to 200x50 on upload."},"imageUrl":{"type":"string","nullable":true,"format":"uri","description":"Optional HTTP/HTTPS URL pointing to a PNG or JPG brand image. Provide `null` to remove the stored image. The source image must be fully opaque; images containing any fully or partially transparent pixels are rejected. The API stores a 200x50 version. Cannot be combined with `imageData`."},"textColor":{"type":"string","nullable":true,"description":"Optional hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"backgroundColor":{"type":"string","nullable":true,"description":"Optional hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"brandColor":{"type":"string","nullable":true,"description":"Optional primary accent hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"accentColor":{"type":"string","nullable":true,"description":"Optional secondary accent hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"}}},"Project":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the project (GUID)"},"name":{"type":"string","description":"Name of the project"},"description":{"type":"string","description":"Detailed description of the project"},"url":{"type":"string","description":"Optional URL associated with the project"},"token":{"type":"string","description":"Client token (owner of the project)"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedOn":{"type":"string","format":"date-time","description":"Last update timestamp"},"active":{"type":"boolean","description":"Whether the project is active"},"imageUrl":{"type":"string","format":"uri","description":"Optional URL of the 200x50 brand image associated with the project"},"textColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"backgroundColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"brandColor":{"type":"string","nullable":true,"description":"Primary branding accent color applied to overlay shapes when branding is configured"},"accentColor":{"type":"string","nullable":true,"description":"Secondary accent color applied to overlay highlights and subtitles when branding is configured"}}}}},"paths":{"/projects/{id}/update":{"post":{"summary":"Update a project","description":"Updates an existing project's name and description.\nOnly the project owner can update their projects.\n\nIf a URL is provided without a description, the API will:\n1. Fetch the website content\n2. Use AI to generate a comprehensive project description in markdown format\n\nEither description or url must be provided.\n","tags":["Projects"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"Project ID (GUID)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectRequest"}}}},"responses":{"200":{"description":"Project updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"project":{"$ref":"#/components/schemas/Project"}}}}}},"400":{"description":"Bad request - Missing required fields or validation error"},"401":{"description":"Unauthorized - valid API token required"},"404":{"description":"Project not found or unauthorized"},"500":{"description":"Internal server error"}}}}}}
```

## Delete a project

> Soft deletes a project (marks it as inactive).\
> Only the project owner can delete their projects.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Projects","description":"Project context management for content generation"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/projects/{id}/delete":{"post":{"summary":"Delete a project","description":"Soft deletes a project (marks it as inactive).\nOnly the project owner can delete their projects.\n","tags":["Projects"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"Project ID (GUID)"}],"responses":{"200":{"description":"Project deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Bad request - Missing project ID"},"401":{"description":"Unauthorized - valid API token required"},"404":{"description":"Project not found or unauthorized"},"500":{"description":"Internal server error"}}}}}}
```


# Feeds

Social media feed management operations

## Get all feeds (public + user's private feeds)

> Retrieves all public feeds (feeds with no token) and user's private feeds if token is provided.\
> \
> \*\*Public Access:\*\*\
> \- Public feeds are available without authentication\
> \- Returns all feeds where token is null\
> \
> \*\*Authenticated Access:\*\*\
> \- Returns public feeds + user's private feeds\
> \- Requires valid API token in Authorization header<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Feeds","description":"Social media feed management operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Feed":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier for the feed"},"name":{"type":"string","description":"Name of the feed"},"token":{"type":"string","description":"Client token (null for public feeds)"},"feedTypeId":{"type":"integer","description":"Type of feed (1 for X/Twitter, 2 for Reddit, 3 for YouTube channel, 4 for RSS, 5 for X News topic)"},"internalId":{"type":"string","description":"Internal identifier for the feed source (username for X, subreddit for Reddit, channel source ID for YouTube)"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"}}}}},"paths":{"/feeds":{"get":{"summary":"Get all feeds (public + user's private feeds)","description":"Retrieves all public feeds (feeds with no token) and user's private feeds if token is provided.\n\n**Public Access:**\n- Public feeds are available without authentication\n- Returns all feeds where token is null\n\n**Authenticated Access:**\n- Returns public feeds + user's private feeds\n- Requires valid API token in Authorization header\n","tags":["Feeds"],"responses":{"200":{"description":"List of feeds (public + user's private feeds)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Feed"}}}}},"500":{"description":"Internal server error"}}}}}}
```

## Create a new feed

> Creates a new feed associated with the authenticated user.\
> \
> \*\*Feed Types:\*\*\
> \- feedTypeId=1: X/Twitter feed (internalId = username)\
> \- feedTypeId=2: Reddit feed (internalId = subreddit name without r/ prefix)\
> \- feedTypeId=3: YouTube channel feed (channel handle/URL, resolved to channel source ID automatically)\
> \- feedTypeId=4: RSS feed (internalId = feed URL)\
> \- feedTypeId=5: X News feed (internalId = topic/search query, e.g. "ai")\
> \
> \*\*Access Control:\*\*\
> \- Requires valid API token\
> \- Feed will be private to the creating user\
> \- PRO subscription required<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Feeds","description":"Social media feed management operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"CreateFeedRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Name of the feed"},"feedTypeId":{"type":"integer","description":"Type of feed (1 for X/Twitter, 2 for Reddit, 3 for YouTube channel, 4 for RSS, 5 for X News topic)"},"internalId":{"type":"string","description":"Internal identifier - Twitter username for X, subreddit name for Reddit (without r/ prefix), topic/search query for X News (feedTypeId=5), feed URL for RSS. For YouTube channels this is populated automatically."},"channel":{"type":"string","description":"(YouTube only) Channel handle, URL, or ID. Either `channel` or `url` may be provided."},"url":{"type":"string","description":"(YouTube only) Channel URL alternative field."}}}}},"paths":{"/feeds":{"post":{"summary":"Create a new feed","description":"Creates a new feed associated with the authenticated user.\n\n**Feed Types:**\n- feedTypeId=1: X/Twitter feed (internalId = username)\n- feedTypeId=2: Reddit feed (internalId = subreddit name without r/ prefix)\n- feedTypeId=3: YouTube channel feed (channel handle/URL, resolved to channel source ID automatically)\n- feedTypeId=4: RSS feed (internalId = feed URL)\n- feedTypeId=5: X News feed (internalId = topic/search query, e.g. \"ai\")\n\n**Access Control:**\n- Requires valid API token\n- Feed will be private to the creating user\n- PRO subscription required\n","tags":["Feeds"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeedRequest"}}}},"responses":{"201":{"description":"Feed created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"feedId":{"type":"integer","description":"ID of the created feed"},"message":{"type":"string"}}}}}},"400":{"description":"Bad request - Missing required fields, feed limit reached, or other validation errors","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"429":{"description":"Rate limit exceeded - too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error during feed creation"}}}}}}
```

## Get a specific feed by ID

> Retrieves a specific feed by its ID.\
> Public feeds are accessible without authentication.\
> Private feeds require appropriate token validation.<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Feeds","description":"Social media feed management operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/feeds/{id}":{"get":{"summary":"Get a specific feed by ID","description":"Retrieves a specific feed by its ID.\nPublic feeds are accessible without authentication.\nPrivate feeds require appropriate token validation.\n","tags":["Feeds"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"integer"},"description":"Feed ID"}],"responses":{"200":{"description":"Feed details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Feed"}}}},"400":{"description":"Bad request - Invalid feed ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"404":{"description":"Feed not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error"}}}}},"components":{"schemas":{"Feed":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier for the feed"},"name":{"type":"string","description":"Name of the feed"},"token":{"type":"string","description":"Client token (null for public feeds)"},"feedTypeId":{"type":"integer","description":"Type of feed (1 for X/Twitter, 2 for Reddit, 3 for YouTube channel, 4 for RSS, 5 for X News topic)"},"internalId":{"type":"string","description":"Internal identifier for the feed source (username for X, subreddit for Reddit, channel source ID for YouTube)"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"}}}}}}
```

## Delete a feed

> Deletes a feed owned by the authenticated user.\
> \
> \*\*Security:\*\*\
> \- Only the feed owner can delete their feeds\
> \- Requires valid API token matching the feed's token<br>

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Feeds","description":"Social media feed management operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"DeleteFeedRequest":{"type":"object","required":["id"],"properties":{"id":{"type":"integer","description":"ID of the feed to delete"}}}}},"paths":{"/feeds/delete":{"post":{"summary":"Delete a feed","description":"Deletes a feed owned by the authenticated user.\n\n**Security:**\n- Only the feed owner can delete their feeds\n- Requires valid API token matching the feed's token\n","tags":["Feeds"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteFeedRequest"}}}},"responses":{"200":{"description":"Feed deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Bad request - Missing or invalid feed ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - valid API token required"},"404":{"description":"Feed not found or cannot be deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error during feed deletion"}}}}}}
```

## List feed subscriptions for the authenticated token

> Returns active feed automations associated with the authenticated user. Use \`includeRemoved=true\` to include archived subscriptions.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Feeds","description":"Social media feed management operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"FeedSubscription":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the subscription"},"feedId":{"type":"integer","description":"Identifier of the subscribed feed"},"token":{"type":"string","description":"Token that owns the subscription"},"requestId":{"type":"string","description":"ClientRequest template identifier used for automation"},"createdOn":{"type":"string","format":"date-time","description":"When the subscription was created"},"removedOn":{"type":"string","format":"date-time","nullable":true,"description":"When the subscription was removed, if applicable"},"lastProcessedItemId":{"type":"string","nullable":true,"description":"Identifier of the last feed item processed for this subscription"},"lastProcessedOn":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of the last processed feed item"},"request":{"type":"object","nullable":true,"description":"Snapshot of the underlying template request"}}}}},"paths":{"/feeds/subscriptions":{"get":{"summary":"List feed subscriptions for the authenticated token","description":"Returns active feed automations associated with the authenticated user. Use `includeRemoved=true` to include archived subscriptions.","tags":["Feeds"],"parameters":[{"in":"query","name":"includeRemoved","schema":{"type":"boolean"},"required":false,"description":"Include subscriptions that have been removed when set to true."}],"responses":{"200":{"description":"Array of feed subscriptions","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FeedSubscription"}}}}},"401":{"description":"Unauthorized - valid API token required"},"500":{"description":"Internal server error while fetching subscriptions"}}}}}}
```

## Create a feed subscription

> Links a feed to a schedule template (ClientRequest) so that new feed items trigger automated content generation.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Feeds","description":"Social media feed management operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"FeedSubscription":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the subscription"},"feedId":{"type":"integer","description":"Identifier of the subscribed feed"},"token":{"type":"string","description":"Token that owns the subscription"},"requestId":{"type":"string","description":"ClientRequest template identifier used for automation"},"createdOn":{"type":"string","format":"date-time","description":"When the subscription was created"},"removedOn":{"type":"string","format":"date-time","nullable":true,"description":"When the subscription was removed, if applicable"},"lastProcessedItemId":{"type":"string","nullable":true,"description":"Identifier of the last feed item processed for this subscription"},"lastProcessedOn":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of the last processed feed item"},"request":{"type":"object","nullable":true,"description":"Snapshot of the underlying template request"}}}}},"paths":{"/feeds/subscriptions":{"post":{"summary":"Create a feed subscription","description":"Links a feed to a schedule template (ClientRequest) so that new feed items trigger automated content generation.","tags":["Feeds"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["feedId","requestId"],"properties":{"feedId":{"type":"integer","description":"Identifier of the feed to subscribe to."},"requestId":{"type":"string","description":"Schedule template (ClientRequest) to clone when new items arrive."},"lastProcessedItemId":{"type":"string","description":"Optional feed item identifier to mark as already processed."}}}}}},"responses":{"201":{"description":"Subscription created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedSubscription"}}}},"400":{"description":"Validation error"},"404":{"description":"Feed or template not found"},"409":{"description":"Subscription already exists for this feed/template pair"},"500":{"description":"Internal server error during creation"}}}}}}
```

## Remove a feed subscription

> Soft-deletes a feed subscription by setting its removedOn timestamp.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Feeds","description":"Social media feed management operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/feeds/subscriptions/{subscriptionId}":{"delete":{"summary":"Remove a feed subscription","description":"Soft-deletes a feed subscription by setting its removedOn timestamp.","tags":["Feeds"],"parameters":[{"in":"path","name":"subscriptionId","required":true,"schema":{"type":"string"},"description":"Identifier of the subscription to remove."}],"responses":{"200":{"description":"Subscription removed"},"400":{"description":"Missing or invalid subscription identifier"},"404":{"description":"Subscription not found or already removed"},"500":{"description":"Internal server error during removal"}}}}}}
```


# Deep Research

Advanced research operations

## Get all deep research requests

> Retrieves all deep research requests made by the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Deep Research","description":"Advanced research operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/deep-research/research":{"get":{"summary":"Get all deep research requests","description":"Retrieves all deep research requests made by the authenticated user","tags":["Deep Research"],"operationId":"getResearches","responses":{"200":{"description":"Successfully retrieved deep research requests","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The request ID"},"requestedOn":{"type":"string","format":"date-time","description":"When the request was made"},"succeededOn":{"type":"string","format":"date-time","description":"When the request was completed"},"status":{"type":"integer","description":"Request status (0=pending, 5=processing, 100=completed)"},"errorOn":{"type":"string","format":"date-time","description":"When the error occurred"},"errorMessage":{"type":"string","description":"Error message if request failed"},"errorCode":{"type":"integer","description":"Error code if request failed"},"prompt":{"type":"string","description":"The research query text"},"outputType":{"type":"string","description":"Output format used for the response (text or json)"},"jsonFormat":{"type":"string","description":"JSON formatting instructions applied when outputType is json"},"isScheduleTemplate":{"type":"boolean","description":"True if this item is a schedule template rather than an executed request"},"scheduleId":{"type":"string","description":"The ID of the schedule template"},"dailyCount":{"type":"integer","description":"Number of times per day this schedule will execute"},"scheduleEndDate":{"type":"string","format":"date-time","description":"End date for the schedule, or null if it runs indefinitely"},"lastScheduleExecutionOn":{"type":"string","format":"date-time","description":"The most recent time this schedule executed"},"nextScheduleExecutionOn":{"type":"string","format":"date-time","description":"The next scheduled execution time"}}}}}}}}}}}}
```

## Perform deep research on a given query

> Conducts advanced research on the provided text query and returns results in the specified output format

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Deep Research","description":"Advanced research operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/deep-research/research":{"post":{"summary":"Perform deep research on a given query","description":"Conducts advanced research on the provided text query and returns results in the specified output format","tags":["Deep Research"],"operationId":"research","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","outputType"],"properties":{"text":{"type":"string","description":"The research query text"},"outputType":{"type":"string","enum":["text","json"],"description":"The format of the output result. When set to json, the response is serialized JSON."},"jsonFormat":{"type":"string","description":"Optional instructions or template describing the JSON structure to generate."},"provider":{"type":"string","enum":["gemini","openai"],"description":"The AI provider to use for research (defaults to gemini)"},"projectIds":{"type":"array","items":{"type":"string"},"description":"Optional array of project IDs to add context from their descriptions"},"files":{"type":"array","description":"Optional array of file URLs or uploaded file IDs (from /files) to attach to the research request","items":{"type":"string"}},"callbackData":{"type":"string","description":"Optional callback data to be returned with the response"},"isScheduled":{"type":"boolean","description":"If true, creates a recurring schedule instead of a one-time request"},"dailyCount":{"type":"integer","minimum":1,"maximum":24,"description":"Number of times per day to execute the research (default 1, only used when isScheduled is true)"},"scheduleEndDate":{"type":"string","format":"date-time","description":"Optional end date for the schedule (only used when isScheduled is true). If not provided, schedule runs indefinitely."}}}}}},"responses":{"200":{"description":"Research request or schedule submitted successfully","content":{"application/json":{"schema":{"oneOf":[{"type":"object","description":"Response for a one-time research request","properties":{"request_id":{"type":"string","description":"The unique ID of the created research request"}}},{"type":"object","description":"Response for a scheduled research request","properties":{"schedule_id":{"type":"string","description":"The unique ID of the created schedule"},"message":{"type":"string","description":"Confirmation message for the schedule"},"dailyCount":{"type":"integer","description":"Number of times per day the research will execute"},"endDate":{"type":"string","format":"date-time","description":"End date for the schedule, or null if no end date"}}}]}}}},"400":{"description":"Bad request - validation error or unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```

## Get a specific deep research request by ID

> Retrieves a single deep research request by its unique ID

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Deep Research","description":"Advanced research operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/deep-research/research/{id}":{"get":{"summary":"Get a specific deep research request by ID","description":"Retrieves a single deep research request by its unique ID","tags":["Deep Research"],"operationId":"getResearchById","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The ID of the deep research request to retrieve"}],"responses":{"200":{"description":"Successfully retrieved deep research request","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The request ID"},"requestedOn":{"type":"string","format":"date-time","description":"When the request was made"},"succeededOn":{"type":"string","format":"date-time","description":"When the request was completed"},"status":{"type":"integer","description":"Request status (0=pending, 5=processing, 100=completed)"},"errorOn":{"type":"string","format":"date-time","description":"When the error occurred"},"errorMessage":{"type":"string","description":"Error message if request failed"},"errorCode":{"type":"integer","description":"Error code if request failed"},"prompt":{"type":"string","description":"The research query text"},"outputType":{"type":"string","description":"Output format used for the response (text or json)"},"jsonFormat":{"type":"string","description":"JSON formatting instructions applied when outputType is json"},"isScheduleTemplate":{"type":"boolean","description":"True if this item is a schedule template rather than an executed request"},"scheduleId":{"type":"string","description":"The ID of the schedule template"},"dailyCount":{"type":"integer","description":"Number of times per day this schedule will execute"},"scheduleEndDate":{"type":"string","format":"date-time","description":"End date for the schedule, or null if it runs indefinitely"},"lastScheduleExecutionOn":{"type":"string","format":"date-time","description":"The most recent time this schedule executed"},"nextScheduleExecutionOn":{"type":"string","format":"date-time","description":"The next scheduled execution time"},"responseText":{"type":"string","description":"The research result content. When outputType is json, this value is a serialized JSON string."}}}}}},"404":{"description":"Deep research request not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```

## Get recurring deep research templates

> Returns all recurring deep research templates for the authenticated user with their configuration and scheduling details.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Deep Research","description":"Advanced research operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/deep-research/recurring":{"get":{"summary":"Get recurring deep research templates","description":"Returns all recurring deep research templates for the authenticated user with their configuration and scheduling details.","tags":["Deep Research"],"responses":{"200":{"description":"Successfully retrieved recurring templates","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unique ID of the recurring template"},"text":{"type":"string","description":"The research query text"},"provider":{"type":"string","enum":["gemini","openai"],"description":"The AI provider for research"},"outputType":{"type":"string","description":"Output format type"},"jsonFormat":{"type":"string","nullable":true,"description":"JSON formatting template applied when outputType is json"},"deletedOn":{"type":"string","format":"date-time","nullable":true,"description":"When the template was deleted (null if not deleted)"},"callbackData":{"type":"string","nullable":true,"description":"User-specific callback data"},"dailyCount":{"type":"integer","description":"Number of executions per day"},"scheduleEndDate":{"type":"string","format":"date-time","nullable":true,"description":"End date for the recurring template (null = indefinite)"},"lastRunAt":{"type":"string","format":"date-time","nullable":true,"description":"Last execution timestamp"},"nextRunAt":{"type":"string","format":"date-time","nullable":true,"description":"Next scheduled execution (null = paused)"},"createdOn":{"type":"string","format":"date-time","description":"Template creation timestamp"}}}}}}}}},"400":{"description":"Bad request - amateur subscription","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```

## Update a recurring deep research template

> Updates specific fields of a recurring template. Can be used to pause/resume, change frequency, update end date, or modify the research text.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Deep Research","description":"Advanced research operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/deep-research/recurring/{id}":{"post":{"summary":"Update a recurring deep research template","description":"Updates specific fields of a recurring template. Can be used to pause/resume, change frequency, update end date, or modify the research text.","tags":["Deep Research"],"parameters":[{"in":"path","name":"id","schema":{"type":"string"},"required":true,"description":"The unique ID of the recurring template to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"New research query text"},"dailyCount":{"type":"integer","minimum":1,"maximum":24,"description":"New number of executions per day"},"scheduleEndDate":{"type":"string","format":"date-time","nullable":true,"description":"New end date for the recurring executions (null to remove end date)"},"isActive":{"type":"boolean","description":"Set to false to pause the recurring template, true to resume"}}}}}},"responses":{"200":{"description":"Recurring template updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"template":{"type":"object","description":"The updated template with all fields (same structure as GET /deep-research/recurring response items)"}}}}}},"400":{"description":"Bad request - validation error or amateur subscription","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"404":{"description":"Recurring template not found or unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```


# X

X (Twitter) operations

## Create an X (Twitter) post or thread request

> Creates a request to generate and publish a tweet or thread from various content sources. Supports immediate execution or scheduling.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"X","description":"X (Twitter) operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/x/post":{"post":{"summary":"Create an X (Twitter) post or thread request","description":"Creates a request to generate and publish a tweet or thread from various content sources. Supports immediate execution or scheduling.","tags":["X"],"operationId":"createPost","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["tweet","thread"],"description":"Whether to create a single tweet or a thread"},"feedIds":{"type":"string","description":"Optional feed IDs to use as content sources (max 10). When using multipart/form-data, send as comma-separated string."},"deepResearchIds":{"type":"string","description":"Optional deep research request IDs to use as content sources (max 10). When using multipart/form-data, send as comma-separated string."},"projectIds":{"type":"string","description":"Optional project IDs to use as context for generation (max 10). When using multipart/form-data, send as comma-separated string."},"audioUrl":{"type":"string","description":"Optional audio URL to transcribe and use as content source"},"promptAudioFile":{"type":"string","format":"binary","description":"Audio file to upload and transcribe as style instructions (alternative to promptAudioUrl)"},"url":{"type":"string","description":"Optional URL to scrape and use as content source"},"text":{"type":"string","description":"Optional raw text to post (or to seed generation)"},"prompt":{"type":"string","description":"Optional style instructions to guide the content generation"},"tweetStyle":{"type":"string","enum":["OneLiner","Paragraphs","Explainer"],"description":"Optional formatting style for the tweet. OneLiner for concise tweets, Paragraphs for story-style tweets, Explainer for educational content. If not specified, a random style will be selected."},"count":{"type":"integer","minimum":1,"maximum":10,"description":"Number of tweets/threads to generate (default 1)"},"deepResearch":{"type":"boolean","description":"If true, triggers deep research to gather additional context and insights before generating the tweet/thread. This enhances the content with supporting evidence, implications, and key learnings."},"imageUrl":{"type":"string","description":"URL to an image to include context from (will be analyzed and described)"},"imageFile":{"type":"string","format":"binary","description":"Image file to upload and include context from (will be analyzed and described). Max 10MB."},"callbackData":{"type":"string","description":"Optional opaque value returned in eventual callbacks"},"isScheduled":{"type":"boolean","description":"If true, creates a recurring schedule instead of a one-time request"},"dailyCount":{"type":"integer","minimum":1,"maximum":100,"description":"Number of times per day to execute when scheduled (default 1)"},"scheduleEndDate":{"type":"string","format":"date-time","description":"Optional end date for the schedule. If not provided, schedule runs indefinitely."}},"oneOf":[{"required":["type","feedIds"]},{"required":["type","deepResearchIds"]},{"required":["type","audioUrl"]},{"required":["type","url"]},{"required":["type","text"]},{"required":["type","imageUrl"]},{"required":["type","imageFile"]}]}},"application/json":{"schema":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["tweet","thread"],"description":"Whether to create a single tweet or a thread"},"feedIds":{"type":"array","items":{"type":"integer"},"description":"Optional feed IDs to use as content sources (max 10)"},"deepResearchIds":{"type":"array","items":{"type":"string"},"description":"Optional deep research request IDs to use as content sources (max 10)"},"projectIds":{"type":"array","items":{"type":"string"},"description":"Optional project IDs to use as context for generation (max 10)"},"audioUrl":{"type":"string","description":"Optional audio URL to transcribe and use as content source"},"promptAudioUrl":{"type":"string","description":"URL to an audio file to transcribe and use as the prompt/style instructions"},"url":{"type":"string","description":"Optional URL to scrape and use as content source"},"text":{"type":"string","description":"Optional raw text to post (or to seed generation)"},"prompt":{"type":"string","description":"Optional style instructions to guide the content generation"},"imageUrl":{"type":"string","description":"URL to an image to include context from (will be analyzed and described)"},"tweetStyle":{"type":"string","enum":["OneLiner","Paragraphs","Explainer"],"description":"Optional formatting style for the tweet. OneLiner for concise tweets, Paragraphs for story-style tweets, Explainer for educational content. If not specified, a random style will be selected."},"count":{"type":"integer","minimum":1,"maximum":10,"description":"Number of tweets/threads to generate (default 1)"},"deepResearch":{"type":"boolean","description":"If true, triggers deep research to gather additional context and insights before generating the tweet/thread. This enhances the content with supporting evidence, implications, and key learnings."},"callbackData":{"type":"string","description":"Optional opaque value returned in eventual callbacks"},"isScheduled":{"type":"boolean","description":"If true, creates a recurring schedule instead of a one-time request"},"dailyCount":{"type":"integer","minimum":1,"maximum":100,"description":"Number of times per day to execute when scheduled (default 1)"},"scheduleEndDate":{"type":"string","format":"date-time","description":"Optional end date for the schedule. If not provided, schedule runs indefinitely."},"imageFile":{"type":"string","description":"Base64 encoded image file to include context from (will be analyzed and described). Cannot be used with imageUrl."}},"oneOf":[{"required":["type","feedIds"]},{"required":["type","deepResearchIds"]},{"required":["type","audioUrl"]},{"required":["type","url"]},{"required":["type","text"]},{"required":["type","imageUrl"]}]}}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"oneOf":[{"type":"object","description":"Response for a one-time X post request","properties":{"request_id":{"type":"string","description":"The unique ID of the created request"}}},{"type":"object","description":"Response for a scheduled X post request","properties":{"schedule_id":{"type":"string","description":"The unique ID of the created schedule"},"message":{"type":"string","description":"Confirmation message for the schedule"},"dailyCount":{"type":"integer","description":"Number of times per day the X post will be created"},"endDate":{"type":"string","format":"date-time","description":"End date for the schedule, or null if no end date"}}}]}}}},"400":{"description":"Bad request - validation error or unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"429":{"description":"Too many requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```

## Quick-create an X (Twitter) post or thread

> Minimal input endpoint. Provide type and either queryText or queryAudioFile, optionally an image.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"X","description":"X (Twitter) operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/x/post/quick":{"post":{"summary":"Quick-create an X (Twitter) post or thread","description":"Minimal input endpoint. Provide type and either queryText or queryAudioFile, optionally an image.","tags":["X"],"operationId":"createPostQuick","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["tweet","thread"],"description":"Whether to create a single tweet or a thread"},"queryText":{"type":"string","description":"Text query to drive the generation (required if queryAudioFile not provided)"},"tweetStyle":{"type":"string","enum":["OneLiner","Paragraphs","Explainer"],"description":"Optional formatting style for the tweet. OneLiner for concise tweets, Paragraphs for story-style tweets, Explainer for educational content. If not specified, a random style will be selected."},"count":{"type":"integer","minimum":1,"maximum":10,"description":"Number of tweets/threads to generate (default 1)"},"deepResearch":{"type":"boolean","description":"If true, triggers deep research to gather additional context and insights before generating the tweet/thread. This enhances the content with supporting evidence, implications, and key learnings."},"queryAudioFile":{"type":"string","format":"binary","description":"Optional audio file to upload and transcribe as the query (required if queryText not provided)"},"imageFile":{"type":"string","format":"binary","description":"Optional image to upload and include context from"}}},"oneOf":[{"required":["type","queryText"]},{"required":["type","queryAudioFile"]}]}}},"responses":{"200":{"description":"Request accepted","content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","description":"The unique ID of the created request"}}}}}},"400":{"description":"Bad request - validation error or unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"429":{"description":"Too many requests - rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```

## Refine an existing X (Twitter) post

> Refines an existing tweet based on user instructions while maintaining context. Costs 1 credit. Can update the tweet text and any associated data tables or charts.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"X","description":"X (Twitter) operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/x/refine":{"post":{"summary":"Refine an existing X (Twitter) post","description":"Refines an existing tweet based on user instructions while maintaining context. Costs 1 credit. Can update the tweet text and any associated data tables or charts.","tags":["X"],"operationId":"refineTweet","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tweetId"],"properties":{"tweetId":{"type":"string","description":"The unique ID of the tweet to refine"},"prompt":{"type":"string","description":"Instructions for how to refine the tweet"},"promptAudioUrl":{"type":"string","description":"URL to an audio file to transcribe and use as refinement instructions. Required if prompt is not provided."}}}}}},"responses":{"200":{"description":"Tweet refined successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"post":{"type":"object","properties":{"id":{"type":"string","description":"The unique ID of the refined tweet"},"requestId":{"type":"string","description":"The original request ID"},"result":{"type":"string","description":"The refined tweet text"},"type":{"type":"string","description":"The post type"},"order":{"type":"integer","description":"Order in thread (0 for single tweets)"},"createdOn":{"type":"string","format":"date-time","description":"Original creation date"},"tweetImageUrl":{"type":"string","nullable":true,"description":"Main image for the tweet if present"},"dataTableImageUrl":{"type":"string","nullable":true,"description":"URL to updated data table image if present"},"barChartImageUrl":{"type":"string","nullable":true,"description":"URL to updated bar chart image if present"}}}}}}}},"400":{"description":"Bad request - validation error or insufficient credits","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"404":{"description":"Tweet not found or unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```

## Get generated X (Twitter) posts for the authenticated user

> Returns the list of generated X posts and threads, including visualization image URLs when available. Supports optional pagination.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"X","description":"X (Twitter) operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"XPost":{"type":"object","properties":{"id":{"type":"string","description":"Unique ID of the post (use this for refinement)"},"requestId":{"type":"string"},"result":{"type":"string","description":"The generated content or metadata"},"type":{"type":"string","description":"The post type (e.g., tweet or thread item)"},"order":{"type":"integer","description":"Order in the thread (starts at 0)"},"createdOn":{"type":"string","format":"date-time"},"tweetImageUrl":{"type":"string","nullable":true,"description":"Main image for the tweet (from user upload or provided URL)"},"dataTableImageUrl":{"type":"string","nullable":true,"description":"Optional URL to a generated data table image"},"barChartImageUrl":{"type":"string","nullable":true,"description":"Optional URL to a generated bar chart image"},"sources":{"type":"array","description":"Provenance entries describing where the content came from","items":{"$ref":"#/components/schemas/XPostSource"}},"shareUrl":{"type":"string","description":"Share URL for the post (only in getPodcasts response)"}}},"XPostSource":{"type":"object","properties":{"type":{"type":"string","description":"Classification of the source (e.g. feed, resource, deep-research)"},"sourceId":{"type":"string","nullable":true,"description":"Optional identifier for the source record"},"reference":{"type":"string","nullable":true,"description":"User-friendly reference like a URL or handle"},"description":{"type":"string","nullable":true,"description":"Short summary of the source content"},"metadata":{"type":"object","nullable":true,"additionalProperties":true,"description":"Arbitrary metadata captured for the source"}}}}},"paths":{"/x/posts":{"get":{"summary":"Get generated X (Twitter) posts for the authenticated user","description":"Returns the list of generated X posts and threads, including visualization image URLs when available. Supports optional pagination.","tags":["X"],"operationId":"getPosts","responses":{"200":{"description":"Successfully retrieved X posts","content":{"application/json":{"schema":{"type":"object","properties":{"posts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unique ID of the post (use this for refinement)"},"requestId":{"type":"string","description":"The request ID that generated this post"},"result":{"type":"string","description":"The tweet text content"},"type":{"type":"string","description":"The post type (tweet or thread item)"},"order":{"type":"integer","description":"Order in thread (starts at 0)"},"createdOn":{"type":"string","format":"date-time","description":"When the post was created"},"tweetImageUrl":{"type":"string","nullable":true,"description":"Main image for the tweet (from user upload or provided URL). When present, visualization images are not generated."},"dataTableImageUrl":{"type":"string","nullable":true,"description":"URL to generated data table image if present"},"barChartImageUrl":{"type":"string","nullable":true,"description":"URL to generated bar chart image if present"}}}}},"oneOf":[{"type":"object","description":"Non-paginated response (when page and limit are not provided)","properties":{"posts":{"type":"array","items":{"$ref":"#/components/schemas/XPost"}}}},{"type":"object","description":"Paginated response (when page or limit are provided)","properties":{"posts":{"type":"array","items":{"$ref":"#/components/schemas/XPost"}},"totalCount":{"type":"integer","description":"Total number of posts"},"page":{"type":"integer","description":"Current page number"},"pageSize":{"type":"integer","description":"Number of items per page"},"totalPages":{"type":"integer","description":"Total number of pages"}}}]}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}},"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"required":false,"description":"Page number for pagination (starts at 1). If not provided, returns all results."},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"description":"Number of items per page (max 100, default 50 if page is specified)"}]}}}}
```

## Get a single generated X (Twitter) post by ID

> Returns a single generated tweet or thread item belonging to the authenticated user by its unique ID.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"X","description":"X (Twitter) operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/x/posts/{id}":{"get":{"summary":"Get a single generated X (Twitter) post by ID","description":"Returns a single generated tweet or thread item belonging to the authenticated user by its unique ID.","tags":["X"],"operationId":"getPostById","parameters":[{"in":"path","name":"id","schema":{"type":"string"},"required":true,"description":"The unique ID of the post to retrieve"}],"responses":{"200":{"description":"Successfully retrieved the X post","content":{"application/json":{"schema":{"type":"object","properties":{"post":{"type":"object","properties":{"id":{"type":"string","description":"Unique ID of the post"},"requestId":{"type":"string","description":"The request ID that generated this post"},"result":{"type":"string","description":"The generated content or metadata"},"type":{"type":"string","description":"The post type (e.g., tweet or thread item)"},"order":{"type":"integer","description":"Order in the thread (starts at 0)"},"createdOn":{"type":"string","format":"date-time","description":"When the post was created"},"tweetImageUrl":{"type":"string","nullable":true,"description":"Main image for the tweet (from user upload or provided URL)"},"dataTableImageUrl":{"type":"string","nullable":true,"description":"Optional URL to a generated data table image"},"barChartImageUrl":{"type":"string","nullable":true,"description":"Optional URL to a generated bar chart image"}}}}}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"404":{"description":"Post not found or unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```

## Get recurring X (Twitter) templates

> Returns all recurring tweet/thread templates for the authenticated user with their configuration and scheduling details.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"X","description":"X (Twitter) operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/x/recurring":{"get":{"summary":"Get recurring X (Twitter) templates","description":"Returns all recurring tweet/thread templates for the authenticated user with their configuration and scheduling details.","tags":["X"],"responses":{"200":{"description":"Successfully retrieved recurring templates","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unique ID of the recurring template"},"type":{"type":"string","enum":["tweet","thread"],"description":"Type of X post to create"},"deletedOn":{"type":"string","format":"date-time","nullable":true,"description":"When the template was deleted (null if not deleted)"},"feedIds":{"type":"array","items":{"type":"integer"},"description":"Feed IDs used as content sources"},"deepResearchIds":{"type":"array","items":{"type":"string"},"description":"Deep research IDs used as content sources"},"projectIds":{"type":"array","items":{"type":"string"},"description":"Project IDs used as context"},"audioUrl":{"type":"string","nullable":true,"description":"Audio URL for transcription"},"url":{"type":"string","nullable":true,"description":"URL for content scraping"},"text":{"type":"string","nullable":true,"description":"Raw text content"},"prompt":{"type":"string","nullable":true,"description":"Style instructions for generation"},"imageUrl":{"type":"string","nullable":true,"description":"Image URL for context"},"promptAudioUrl":{"type":"string","nullable":true,"description":"Audio URL for prompt instructions"},"queryText":{"type":"string","nullable":true,"description":"Quick mode query text"},"queryAudioUrl":{"type":"string","nullable":true,"description":"Quick mode query audio URL"},"fast":{"type":"boolean","nullable":true,"description":"Whether this is a quick mode template"},"tweetStyle":{"type":"string","enum":["OneLiner","Paragraphs","Explainer"],"nullable":true,"description":"Formatting style for tweets. OneLiner for concise tweets, Paragraphs for story-style tweets, Explainer for educational content."},"callbackData":{"type":"string","nullable":true,"description":"User-specific callback data"},"dailyCount":{"type":"integer","description":"Number of executions per day"},"scheduleEndDate":{"type":"string","format":"date-time","nullable":true,"description":"End date for the recurring template (null = indefinite)"},"lastRunAt":{"type":"string","format":"date-time","nullable":true,"description":"Last execution timestamp"},"nextRunAt":{"type":"string","format":"date-time","nullable":true,"description":"Next scheduled execution (null = paused)"},"createdOn":{"type":"string","format":"date-time","description":"Template creation timestamp"}}}}}}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```

## Update a recurring X (Twitter) template

> Updates specific fields of a recurring template. Can be used to pause/resume, change frequency, update end date, or modify prompt.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"X","description":"X (Twitter) operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/x/recurring/{id}":{"post":{"summary":"Update a recurring X (Twitter) template","description":"Updates specific fields of a recurring template. Can be used to pause/resume, change frequency, update end date, or modify prompt.","tags":["X"],"parameters":[{"in":"path","name":"id","schema":{"type":"string"},"required":true,"description":"The unique ID of the recurring template to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","description":"New style instructions for generation"},"dailyCount":{"type":"integer","minimum":1,"maximum":100,"description":"New number of executions per day"},"scheduleEndDate":{"type":"string","format":"date-time","nullable":true,"description":"New end date for the recurring executions (null to remove end date)"},"isActive":{"type":"boolean","description":"Set to false to pause the recurring template, true to resume"},"feedIds":{"type":"array","items":{"type":"integer"},"description":"Feed IDs to use as content sources (replaces existing)"},"deepResearchIds":{"type":"array","items":{"type":"string"},"description":"Deep research template IDs to use as content sources (replaces existing)"}}}}}},"responses":{"200":{"description":"Recurring template updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"template":{"type":"object","description":"The updated template with all fields (same structure as GET /x/recurring response items)"}}}}}},"400":{"description":"Bad request - validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"404":{"description":"Recurring template not found or unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}}
```


# Infographics

Infographic assets generated per token

## Get infographics

> Returns paginated infographics created by the authenticated token, including in-progress requests (default 20 per page, max 100).

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Infographics","description":"Infographic assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Infographic":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the infographic (matches request id)"},"imageUrl":{"type":"string","format":"uri","nullable":true,"description":"URL of the generated infographic image (null while processing)"},"title":{"type":"string","nullable":true,"description":"Optional title for the infographic"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the infographic was created (or requested if still in progress)"}}}}},"paths":{"/infographics/get":{"get":{"summary":"Get infographics","description":"Returns paginated infographics created by the authenticated token, including in-progress requests (default 20 per page, max 100).","tags":["Infographics"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"description":"Page number (default 1)"},{"in":"query","name":"pageSize","schema":{"type":"integer","minimum":1,"maximum":100},"description":"Items per page (default 20, max 100)"}],"responses":{"200":{"description":"Paginated list of infographics","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Infographic"}},"totalCount":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"totalPages":{"type":"integer"}}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Download infographic

> Streams the generated infographic image for the authenticated token.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Infographics","description":"Infographic assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/infographics/{infographicId}/download":{"get":{"summary":"Download infographic","description":"Streams the generated infographic image for the authenticated token.","tags":["Infographics"],"parameters":[{"in":"path","name":"infographicId","required":true,"schema":{"type":"string"},"description":"Infographic request identifier"}],"responses":{"200":{"description":"Binary infographic image stream","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Infographic not found or not ready"},"502":{"description":"Upstream asset unavailable"}}}}}}
```


# Data Tables

Data table assets generated per token

## Get data tables

> Returns paginated data tables created by the authenticated token, including in-progress requests (default 20 per page, max 100).

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Data Tables","description":"Data table assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"DataTable":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the data table (matches request id)"},"url":{"type":"string","format":"uri","nullable":true,"description":"URL of the generated data table file (null while processing)"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the data table was created (or requested if still in progress)"}}}}},"paths":{"/data-tables/get":{"get":{"summary":"Get data tables","description":"Returns paginated data tables created by the authenticated token, including in-progress requests (default 20 per page, max 100).","tags":["Data Tables"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"description":"Page number (default 1)"},{"in":"query","name":"pageSize","schema":{"type":"integer","minimum":1,"maximum":100},"description":"Items per page (default 20, max 100)"}],"responses":{"200":{"description":"Paginated list of data tables","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DataTable"}},"totalCount":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"totalPages":{"type":"integer"}}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Download data table

> Streams the generated data table file for the authenticated token.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Data Tables","description":"Data table assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/data-tables/{dataTableId}/download":{"get":{"summary":"Download data table","description":"Streams the generated data table file for the authenticated token.","tags":["Data Tables"],"parameters":[{"in":"path","name":"dataTableId","required":true,"schema":{"type":"string"},"description":"Data table request identifier"}],"responses":{"200":{"description":"Binary data table file stream","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Data table not found or not ready"},"502":{"description":"Upstream asset unavailable"}}}}}}
```


# Quizzes

Quiz assets generated per token

## Get quizzes

> Returns paginated quizzes created by the authenticated token, including in-progress requests (default 20 per page, max 100).

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Quizzes","description":"Quiz assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Quiz":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the quiz (matches request id)"},"quizJson":{"type":"string","nullable":true,"description":"Quiz JSON content (null while processing)"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the quiz was created (or requested if still in progress)"}}}}},"paths":{"/quizzes/get":{"get":{"summary":"Get quizzes","description":"Returns paginated quizzes created by the authenticated token, including in-progress requests (default 20 per page, max 100).","tags":["Quizzes"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"description":"Page number (default 1)"},{"in":"query","name":"pageSize","schema":{"type":"integer","minimum":1,"maximum":100},"description":"Items per page (default 20, max 100)"}],"responses":{"200":{"description":"Paginated list of quizzes","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Quiz"}},"totalCount":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"totalPages":{"type":"integer"}}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Download quiz

> Downloads the generated quiz JSON for the authenticated token.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Quizzes","description":"Quiz assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/quizzes/{quizId}/download":{"get":{"summary":"Download quiz","description":"Downloads the generated quiz JSON for the authenticated token.","tags":["Quizzes"],"parameters":[{"in":"path","name":"quizId","required":true,"schema":{"type":"string"},"description":"Quiz request identifier"}],"responses":{"200":{"description":"Quiz JSON download","content":{"application/json":{"schema":{"type":"string"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Quiz not found or not ready"}}}}}}
```


# Documents

Briefing document assets generated per token

## Get documents

> Returns paginated briefing documents created by the authenticated token, including in-progress requests.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Documents","description":"Briefing document assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Document":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the document (matches request id)"},"type":{"type":"string","description":"Document type"},"format":{"type":"string","enum":["text","html","pdf"],"description":"Stored result format"},"title":{"type":"string","nullable":true,"description":"Optional document title"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the document row was created"},"content":{"type":"string","nullable":true,"description":"Text or HTML content when format is `text` or `html`"},"url":{"type":"string","nullable":true,"description":"Direct PDF URL when format is `pdf`"}}}}},"paths":{"/documents/get":{"get":{"summary":"Get documents","description":"Returns paginated briefing documents created by the authenticated token, including in-progress requests.","tags":["Documents"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"description":"Page number (default 1)"},{"in":"query","name":"pageSize","schema":{"type":"integer","minimum":1,"maximum":100},"description":"Items per page (default 20, max 100)"}],"responses":{"200":{"description":"Paginated list of documents","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Document"}},"totalCount":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"totalPages":{"type":"integer"}}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Get document

> Returns the stored briefing document payload for the authenticated token.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Documents","description":"Briefing document assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Document":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the document (matches request id)"},"type":{"type":"string","description":"Document type"},"format":{"type":"string","enum":["text","html","pdf"],"description":"Stored result format"},"title":{"type":"string","nullable":true,"description":"Optional document title"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the document row was created"},"content":{"type":"string","nullable":true,"description":"Text or HTML content when format is `text` or `html`"},"url":{"type":"string","nullable":true,"description":"Direct PDF URL when format is `pdf`"}}}}},"paths":{"/documents/{documentId}":{"get":{"summary":"Get document","description":"Returns the stored briefing document payload for the authenticated token.","tags":["Documents"],"parameters":[{"in":"path","name":"documentId","required":true,"schema":{"type":"string"},"description":"Document request identifier"}],"responses":{"200":{"description":"Document payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Document not found"}}}}}}
```

## Download document

> Downloads the stored briefing document as PDF, HTML, or text for the authenticated token.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Documents","description":"Briefing document assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/documents/{documentId}/download":{"get":{"summary":"Download document","description":"Downloads the stored briefing document as PDF, HTML, or text for the authenticated token.","tags":["Documents"],"parameters":[{"in":"path","name":"documentId","required":true,"schema":{"type":"string"},"description":"Document request identifier"}],"responses":{"200":{"description":"Document download","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Document not found or not ready"},"502":{"description":"Upstream asset unavailable"}}}}}}
```

## Preview document

> Streams the stored briefing document inline using its native format. Supports PDF, HTML, and plain text documents for the authenticated token.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Documents","description":"Briefing document assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/documents/{documentId}/preview":{"get":{"summary":"Preview document","description":"Streams the stored briefing document inline using its native format. Supports PDF, HTML, and plain text documents for the authenticated token.","tags":["Documents"],"parameters":[{"in":"path","name":"documentId","required":true,"schema":{"type":"string"},"description":"Document request identifier"}],"responses":{"200":{"description":"Document preview","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"text/html":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Document not found or not ready"},"502":{"description":"Upstream asset unavailable"}}}}}}
```


# Files

Upload and manage private files for resources

## GET /files

> List uploaded files for the authenticated token

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Files","description":"Upload and manage private files for resources"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/files":{"get":{"summary":"List uploaded files for the authenticated token","tags":["Files"],"responses":{"200":{"description":"List of files"},"401":{"description":"Unauthorized"}}}}}}
```

## POST /files

> Upload a private file for later use as a content resource

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Files","description":"Upload and manage private files for resources"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/files":{"post":{"summary":"Upload a private file for later use as a content resource","tags":["Files"],"consumes":["multipart/form-data"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"File to upload (max 200MB)"}}}}}},"responses":{"200":{"description":"File uploaded"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"}}}}}}
```

## DELETE /files/{id}

> Delete an uploaded file by id

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Files","description":"Upload and manage private files for resources"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/files/{id}":{"delete":{"summary":"Delete an uploaded file by id","tags":["Files"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"File id returned by the upload endpoint"}],"responses":{"200":{"description":"File deleted"},"401":{"description":"Unauthorized"},"404":{"description":"File not found"}}}}}}
```


# Slide Decks

Slide deck assets generated per token

## Get slide decks

> Returns paginated slide decks created by the authenticated token, including in-progress requests (default 20 per page, max 100).

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Slide Decks","description":"Slide deck assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"SlideDeck":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the slide deck (matches request id)"},"url":{"type":"string","format":"uri","nullable":true,"description":"URL of the generated slide deck (null while processing)"},"title":{"type":"string","nullable":true,"description":"Optional title for the slide deck"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the slide deck was created (or requested if still in progress)"}}}}},"paths":{"/slide-decks/get":{"get":{"summary":"Get slide decks","description":"Returns paginated slide decks created by the authenticated token, including in-progress requests (default 20 per page, max 100).","tags":["Slide Decks"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","minimum":1},"description":"Page number (default 1)"},{"in":"query","name":"pageSize","schema":{"type":"integer","minimum":1,"maximum":100},"description":"Items per page (default 20, max 100)"}],"responses":{"200":{"description":"Paginated list of slide decks","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SlideDeck"}},"totalCount":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"totalPages":{"type":"integer"}}}}}},"401":{"description":"Unauthorized"}}}}}}
```

## Download slide deck

> Streams the generated slide deck file (PDF or PPT) for the authenticated token.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Slide Decks","description":"Slide deck assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/slide-decks/{slideDeckId}/download":{"get":{"summary":"Download slide deck","description":"Streams the generated slide deck file (PDF or PPT) for the authenticated token.","tags":["Slide Decks"],"parameters":[{"in":"path","name":"slideDeckId","required":true,"schema":{"type":"string"},"description":"Slide deck request identifier"}],"responses":{"200":{"description":"Binary slide deck stream","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Slide deck not found or not ready"},"502":{"description":"Upstream asset unavailable"}}}}}}
```

## Preview slide deck

> Streams the generated slide deck file inline for browser previews.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Slide Decks","description":"Slide deck assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/slide-decks/{slideDeckId}/preview":{"get":{"summary":"Preview slide deck","description":"Streams the generated slide deck file inline for browser previews.","tags":["Slide Decks"],"parameters":[{"in":"path","name":"slideDeckId","required":true,"schema":{"type":"string"},"description":"Slide deck request identifier"}],"responses":{"200":{"description":"Inline slide deck stream","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/vnd.ms-powerpoint":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Slide deck not found or not ready"},"502":{"description":"Upstream asset unavailable"}}}}}}
```

## Public preview slide deck

> Streams the slide deck inline without authentication for marketing/demo pages.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Slide Decks","description":"Slide deck assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/slide-decks/public/{slideDeckId}/preview":{"get":{"summary":"Public preview slide deck","description":"Streams the slide deck inline without authentication for marketing/demo pages.","tags":["Slide Decks"],"parameters":[{"in":"path","name":"slideDeckId","required":true,"schema":{"type":"string"},"description":"Slide deck request identifier"}],"responses":{"200":{"description":"Inline slide deck stream","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Slide deck not found or not ready"},"502":{"description":"Upstream asset unavailable"}}}}}}
```

## Public preview slide deck by URL

> Streams a whitelisted slide deck URL inline (PDF) without authentication.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Slide Decks","description":"Slide deck assets generated per token"}],"servers":[{"url":"https://api.autocontentapi.com"}],"paths":{"/slide-decks/public-preview":{"get":{"summary":"Public preview slide deck by URL","description":"Streams a whitelisted slide deck URL inline (PDF) without authentication.","tags":["Slide Decks"],"parameters":[{"in":"query","name":"url","required":true,"schema":{"type":"string","format":"uri"},"description":"Direct URL to the slide deck asset (limited to autocontentapi.blob.core.windows.net)"}],"responses":{"200":{"description":"Inline slide deck stream","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Missing or invalid URL"},"502":{"description":"Upstream asset unavailable"}}}}}}
```


# Billing

Billing and invoices operations

## Get Stripe invoices for the authenticated client

> Resolves the authenticated token to the client's email and returns matching Stripe invoices.

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"tags":[{"name":"Billing","description":"Billing and invoices operations"}],"servers":[{"url":"https://api.autocontentapi.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/billing/invoices":{"get":{"summary":"Get Stripe invoices for the authenticated client","description":"Resolves the authenticated token to the client's email and returns matching Stripe invoices.","tags":["Billing"],"responses":{"200":{"description":"List of invoices","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"invoiceid":{"type":"string"},"invoice_url":{"type":"string","nullable":true},"receipt_url":{"type":"string","nullable":true},"date":{"type":"string","format":"date-time"}}}}}}},"401":{"description":"Unauthorized"},"500":{"description":"Internal server error"}}}}}}
```


# Models

## The ContentRequest object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"ContentRequest":{"type":"object","required":["outputType"],"properties":{"resources":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["text","youtube","website","pdf","file"]},"content":{"type":"string","description":"For type \"file\", provide an https URL or a file id returned by POST /files. For other types, provide the text or URL expected by that type."}}},"description":"Resources for content generation (required if topic, feedSelections, or researches are not provided)"},"topic":{"type":"string","description":"Topic for content generation (alternative to resources, feedSelections, or researches)"},"feedSelections":{"type":"array","description":"Cached feed items to include in the request (alternative to resources, topic, or researches)","items":{"$ref":"#/components/schemas/FeedSelection"}},"researches":{"type":"array","items":{"type":"string"},"description":"Array of research IDs to include as text resources (max 10)"},"projects":{"type":"array","items":{"type":"string"},"description":"Array of project IDs to use as context for generation (max 10)"},"logoUrl":{"type":"string","format":"uri","description":"Optional HTTP or HTTPS PNG/JPG image URL for video, infographic, and slide_deck requests. Any source dimensions are accepted, but the image must be fully opaque and no larger than 5 MB; it is normalized to an opaque 200x50 PNG using the same rules as a project image. When supplied, it overrides the project logo for this request while project context and branding colors still apply. When omitted, the project logo and then the default logo are used."},"youtubeChannels":{"type":"array","items":{"type":"string"},"description":"YouTube channel IDs already connected to the account to use as sources"},"podcastEpisodeIds":{"type":"array","items":{"type":"string"},"description":"Completed audio request IDs to reuse as podcast episode sources (max 10)"},"text":{"type":"string","description":"Instructions or query for content generation"},"outputType":{"type":"string","enum":["audio","text","faq","study_guide","timeline","briefing_doc","quiz","video","infographic","slide_deck","datatable"],"description":"Type of output content to generate"},"duration":{"type":"string","enum":["short","default","long"],"description":"Duration preference for audio and slide deck generation. Ignored for video requests."},"format":{"type":"string","enum":["explainer","short","cinematic","text","html","pdf"],"description":"For `video`, accepted values are `explainer`, `short`, and `cinematic` (defaults to `explainer`). `cinematic` video requests cost 100 credits. For `briefing_doc`, accepted values are `text`, `html`, and `pdf` (defaults to `pdf`). Ignored for other output types."},"style":{"type":"string","description":"Style of the generated content. For audio/text, use one of: deep dive, brief, critique, debate. For video, any custom style text is accepted (defaults to classic when omitted).\n"},"introMusicUrl":{"type":"string","description":"HTTPS URL to optional intro music (.mp3, .wav, or .m4a) mixed at lower volume at the start of the podcast"},"includeCitations":{"type":"boolean","description":"Whether to include citations (PRO only)"},"ignorePaywalledResources":{"type":"boolean","description":"When true, continue processing even if some URL resources fail to import (paywall/restrictions). The request fails only if none of the provided resources are successfully imported."},"infographicOrientation":{"type":"string","enum":["landscape","portrait","square"],"description":"Infographic orientation (defaults to landscape)"},"infographicDetail":{"type":"string","enum":["concise","standard","detailed"],"description":"Infographic detail level (defaults to standard)"},"slideDeckFormat":{"type":"string","enum":["detailed","presenter"],"description":"Slide deck format (defaults to detailed). Length is controlled via the standard duration field (short, default, long). Slide deck prompt uses the main text field."},"quizDifficulty":{"type":"string","enum":["easy","medium","hard"],"description":"Difficulty level for quiz outputs (defaults to medium). Quiz prompt uses the main text field."},"callbackData":{"type":"string","maxLength":500,"description":"Optional data to include in webhooks (maximum 500 characters)"},"relatedId":{"type":"string","description":"Existing request ID to relate this request to (must belong to the same token)"},"notebookId":{"type":"string","description":"Owned Private Notebook ID. When present, generation uses that notebook's saved sources and its license's exact dedicated account, follows Private Notebooks capacity instead of content credits, and rejects additional request sources or generic topic/project inputs."},"language":{"type":"string","description":"Language for content generation"},"scheduledOn":{"type":"string","format":"date-time","description":"Schedule the content generation for a specific time"},"podcastId":{"type":"string","description":"Podcast show ID to associate this content with"},"episodeTitle":{"type":"string","description":"Optional episode title when attaching to a podcast show"},"title":{"type":"string","description":"Custom title to use for generated video outputs. When provided, overrides the automatically generated title."},"titlePrompt":{"type":"string","description":"Prompt to guide the generated video title"},"descriptionPrompt":{"type":"string","description":"Prompt to guide the generated video description"},"thumbnailImagePrompt":{"type":"string","description":"Prompt to control the generated thumbnail image for video outputs"},"introImagePrompt":{"type":"string","description":"Prompt to control the intro image for video outputs"},"voice1":{"type":"integer","description":"Primary custom voice id from /content/GetVoices. Use the numeric id value, not the voice name."},"voice2":{"type":"integer","description":"Secondary custom voice id from /content/GetVoices. Requires voice1."},"publishTargets":{"type":"array","description":"Targets to publish generated videos to (e.g., YouTube)","items":{"$ref":"#/components/schemas/PublishTarget"}},"templateMode":{"type":"object","description":"Create a reusable template instead of processing immediately","properties":{"type":{"type":"string","enum":["feed"]},"name":{"type":"string","description":"Optional display name for the template"}}},"isScheduled":{"type":"boolean","description":"Create a recurring schedule instead of a single request"},"dailyCount":{"type":"integer","minimum":1,"maximum":24,"description":"Number of times per day to run when isScheduled is true"},"scheduleEndDate":{"type":"string","format":"date-time","description":"Optional end date for recurring schedules (requires isScheduled true)"}}},"FeedSelection":{"type":"object","required":["feedId","feedItemIds"],"properties":{"feedId":{"type":"integer","description":"Identifier of the feed containing the cached items"},"feedItemIds":{"type":"array","items":{"type":"string"},"description":"Identifiers of cached posts or videos to include from that feed"}}},"PublishTarget":{"type":"object","properties":{"channel":{"type":"string","description":"Target channel for publishing (e.g., youtube)"},"youtubeAccountId":{"type":"string","nullable":true,"description":"Connected YouTube account ID to publish to"},"youtubePlaylistId":{"type":"string","nullable":true,"description":"Optional playlist ID to publish into"}}}}}}
```

## The RepurposeRequest object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"RepurposeRequest":{"type":"object","required":["requestId","outputType"],"properties":{"requestId":{"type":"string","description":"Identifier of the completed request to repurpose"},"outputType":{"type":"string","enum":["audio","video","infographic","slide_deck","datatable","quiz"],"description":"Output type for the new request"},"language":{"type":"string","description":"Optional language override for the new request (defaults to the original request language)"},"text":{"type":"string","description":"Optional text instructions that replace the original TEXT parameter"},"callbackData":{"type":"string","description":"Optional callback data to associate with the new request"},"duration":{"type":"string","enum":["short","default","long"],"description":"Duration preference for audio and slide deck repurpose requests. Ignored for video requests."},"infographicOrientation":{"type":"string","enum":["landscape","portrait","square"],"description":"Orientation when repurposing to an infographic"},"infographicDetail":{"type":"string","enum":["concise","standard","detailed"],"description":"Detail level when repurposing to an infographic"},"slideDeckFormat":{"type":"string","enum":["detailed","presenter"],"description":"Format when repurposing to a slide deck"},"quizDifficulty":{"type":"string","enum":["easy","medium","hard"],"description":"Difficulty level when repurposing to a quiz"},"title":{"type":"string","description":"Override video title when repurposing to video"},"titlePrompt":{"type":"string","description":"Prompt to guide the generated title when repurposing to video"},"descriptionPrompt":{"type":"string","description":"Prompt to guide the generated description when repurposing to video"},"format":{"type":"string","enum":["explainer","short","cinematic"],"description":"Video format (defaults to explainer). Only applies when outputType is video. `cinematic` costs 100 credits."},"style":{"type":"string","description":"Custom style text for video outputs"},"thumbnailImagePrompt":{"type":"string","description":"Prompt to control the generated thumbnail image for video outputs"},"introImagePrompt":{"type":"string","description":"Prompt to control the generated intro image for video outputs"},"avatarId":{"type":"integer","description":"Optional avatar identifier for explainer video generation. If omitted, inherits from the source request when available."},"audioLanguage":{"type":"string","description":"Optional audio language override for explainer video generation metadata. If omitted, inherits from the source request when available."},"textLanguage":{"type":"string","description":"Optional text language override for explainer video generation metadata. If omitted, inherits from the source request when available."},"backgroundImageUrl":{"type":"string","description":"Optional background image URL for explainer video generation metadata. If omitted, inherits from the source request when available."},"voiceId":{"type":"integer","description":"Optional voice id from /content/GetVoices for explainer video metadata. Use the numeric id value, not the voice name. If omitted, inherits from the source request when available."}}}}}}
```

## The PublishTarget object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"PublishTarget":{"type":"object","properties":{"channel":{"type":"string","description":"Target channel for publishing (e.g., youtube)"},"youtubeAccountId":{"type":"string","nullable":true,"description":"Connected YouTube account ID to publish to"},"youtubePlaylistId":{"type":"string","nullable":true,"description":"Optional playlist ID to publish into"}}}}}}
```

## The FeedSelection object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"FeedSelection":{"type":"object","required":["feedId","feedItemIds"],"properties":{"feedId":{"type":"integer","description":"Identifier of the feed containing the cached items"},"feedItemIds":{"type":"array","items":{"type":"string"},"description":"Identifiers of cached posts or videos to include from that feed"}}}}}}
```

## The RecurringSchedule object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"RecurringSchedule":{"type":"object","properties":{"id":{"type":"string"},"prompt":{"type":"string"},"outputType":{"type":"string"},"format":{"type":"string","nullable":true,"description":"Video format for recurring video schedules (`explainer`, `short`, or `cinematic`). `cinematic` costs 100 credits."},"language":{"type":"string"},"duration":{"type":"string","description":"Duration preference for audio and slide deck schedules. Video schedules do not use duration."},"style":{"type":"string"},"dailyCount":{"type":"integer"},"scheduleEndDate":{"type":"string","format":"date-time","nullable":true},"lastRunAt":{"type":"string","format":"date-time","nullable":true},"nextRunAt":{"type":"string","format":"date-time","nullable":true},"createdOn":{"type":"string","format":"date-time","nullable":true},"podcastId":{"type":"string","nullable":true},"episodeTitle":{"type":"string","nullable":true},"status":{"type":"string","enum":["active","paused","completed"]}}}}}}
```

## The RecurringScheduleDetail object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"RecurringScheduleDetail":{"type":"object","allOf":[{"$ref":"#/components/schemas/RecurringSchedule"},{"type":"object","properties":{"resources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"type":{"type":"string"},"content":{"type":"string"}}}}}}]},"RecurringSchedule":{"type":"object","properties":{"id":{"type":"string"},"prompt":{"type":"string"},"outputType":{"type":"string"},"format":{"type":"string","nullable":true,"description":"Video format for recurring video schedules (`explainer`, `short`, or `cinematic`). `cinematic` costs 100 credits."},"language":{"type":"string"},"duration":{"type":"string","description":"Duration preference for audio and slide deck schedules. Video schedules do not use duration."},"style":{"type":"string"},"dailyCount":{"type":"integer"},"scheduleEndDate":{"type":"string","format":"date-time","nullable":true},"lastRunAt":{"type":"string","format":"date-time","nullable":true},"nextRunAt":{"type":"string","format":"date-time","nullable":true},"createdOn":{"type":"string","format":"date-time","nullable":true},"podcastId":{"type":"string","nullable":true},"episodeTitle":{"type":"string","nullable":true},"status":{"type":"string","enum":["active","paused","completed"]}}}}}}
```

## The WebsiteDiscoveryLink object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"WebsiteDiscoveryLink":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"}}}}}}
```

## The Citation object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Citation":{"type":"object","properties":{"text":{"type":"string","description":"Citation text"},"source":{"type":"string","description":"Source of the citation"},"page":{"type":"integer","description":"Page number for PDF sources"},"timeMs":{"type":"integer","description":"Timestamp in milliseconds for audio/video sources"}}}}}}
```

## The Usage object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Usage":{"type":"object","properties":{"allowed":{"type":"integer","description":"Total credits allowed"},"used":{"type":"integer","description":"Total credits used"},"allowedDailyPodcasts":{"type":"integer","description":"Daily podcast limit"},"usedDailyPodcasts":{"type":"integer","description":"Podcasts created today"}}}}}}
```

## The QueueStats object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"QueueStats":{"type":"object","properties":{"success":{"type":"boolean"},"queued":{"type":"integer","description":"Requests waiting to be picked up for processing"},"processing":{"type":"integer","description":"Requests currently in progress"},"active":{"type":"integer","description":"queued + processing"}}}}}}
```

## The QueueRequestSummary object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"QueueRequestSummary":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"integer"},"request_type_id":{"type":"integer"},"output_type":{"type":"string","nullable":true},"requested_on":{"type":"string","format":"date-time","nullable":true},"processing_on":{"type":"string","format":"date-time","nullable":true},"scheduled_on":{"type":"string","format":"date-time","nullable":true}}}}}}
```

## The QueueRequestsResponse object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"QueueRequestsResponse":{"type":"object","properties":{"success":{"type":"boolean"},"state":{"type":"string","enum":["queued","processing","active"]},"ids":{"type":"array","items":{"type":"string"}},"items":{"type":"array","items":{"$ref":"#/components/schemas/QueueRequestSummary"}},"count":{"type":"integer","description":"Number of items in this page"},"total_count":{"type":"integer"},"page":{"type":"integer"},"page_size":{"type":"integer"},"total_pages":{"type":"integer"}}},"QueueRequestSummary":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"integer"},"request_type_id":{"type":"integer"},"output_type":{"type":"string","nullable":true},"requested_on":{"type":"string","format":"date-time","nullable":true},"processing_on":{"type":"string","format":"date-time","nullable":true},"scheduled_on":{"type":"string","format":"date-time","nullable":true}}}}}}
```

## The Podcast object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Podcast":{"type":"object","properties":{"id":{"type":"string","description":"Podcast ID"},"requestTypeId":{"type":"integer","description":"Type of podcast request"},"audioTitle":{"type":"string","description":"Title of the podcast"},"audioUrl":{"type":"string","description":"URL to the audio file"},"responseText":{"type":"string","description":"Podcast transcript/text"},"requestedOn":{"type":"string","format":"date-time","description":"When the podcast was requested"},"succeededOn":{"type":"string","format":"date-time","description":"When the podcast was completed"},"errorOn":{"type":"string","format":"date-time","description":"When the podcast failed (if applicable)"},"processingOn":{"type":"string","format":"date-time","description":"When the podcast started processing (if applicable)"},"errorMessage":{"type":"string","description":"Error message if the podcast failed"},"status":{"type":"integer","description":"Current status of the podcast"},"shareUrl":{"type":"string","description":"Public sharing URL for the podcast"}}}}}}
```

## The Transcript object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Transcript":{"type":"object","properties":{"id":{"type":"string","description":"Transcript ID"},"audioTitle":{"type":"string","description":"Title of the original audio"},"audioUrl":{"type":"string","description":"URL to the original audio file"},"responseText":{"type":"string","description":"The transcript text content"},"requestedOn":{"type":"string","format":"date-time","description":"When the transcript was requested"},"succeededOn":{"type":"string","format":"date-time","description":"When the transcript was completed"},"errorOn":{"type":"string","format":"date-time","description":"When the transcript failed (if applicable)"},"processingOn":{"type":"string","format":"date-time","description":"When the transcript started processing (if applicable)"},"errorMessage":{"type":"string","description":"Error message if the transcript failed"},"status":{"type":"integer","description":"Current status of the transcript"},"language":{"type":"string","description":"Language of the transcript"},"callbackData":{"type":"string","description":"Optional callback data provided during request"},"scheduledOn":{"type":"string","format":"date-time","description":"When the transcript was scheduled"}}}}}}
```

## The DataTable object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"DataTable":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the data table (matches request id)"},"url":{"type":"string","format":"uri","nullable":true,"description":"URL of the generated data table file (null while processing)"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the data table was created (or requested if still in progress)"}}}}}}
```

## The Document object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Document":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the document (matches request id)"},"type":{"type":"string","description":"Document type"},"format":{"type":"string","enum":["text","html","pdf"],"description":"Stored result format"},"title":{"type":"string","nullable":true,"description":"Optional document title"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the document row was created"},"content":{"type":"string","nullable":true,"description":"Text or HTML content when format is `text` or `html`"},"url":{"type":"string","nullable":true,"description":"Direct PDF URL when format is `pdf`"}}}}}}
```

## The Infographic object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Infographic":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the infographic (matches request id)"},"imageUrl":{"type":"string","format":"uri","nullable":true,"description":"URL of the generated infographic image (null while processing)"},"title":{"type":"string","nullable":true,"description":"Optional title for the infographic"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the infographic was created (or requested if still in progress)"}}}}}}
```

## The Quiz object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Quiz":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the quiz (matches request id)"},"quizJson":{"type":"string","nullable":true,"description":"Quiz JSON content (null while processing)"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the quiz was created (or requested if still in progress)"}}}}}}
```

## The SlideDeck object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"SlideDeck":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the slide deck (matches request id)"},"url":{"type":"string","format":"uri","nullable":true,"description":"URL of the generated slide deck (null while processing)"},"title":{"type":"string","nullable":true,"description":"Optional title for the slide deck"},"status":{"type":"integer","description":"Current progress percentage (100 when completed)"},"createdOn":{"type":"string","format":"date-time","description":"UTC timestamp when the slide deck was created (or requested if still in progress)"}}}}}}
```

## The Avatar object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Avatar":{"type":"object","properties":{"id":{"type":"string","description":"Avatar identifier"},"name":{"type":"string","description":"Avatar display name"},"gender":{"type":"string","enum":["M","F"],"description":"Avatar gender (M = Male, F = Female)"}}}}}}
```

## The Short object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Short":{"type":"object","properties":{"id":{"type":"string","description":"Short video identifier"},"status":{"type":"integer","description":"Status code (0 = pending, 10-90 = processing, 100 = completed, -1 = failed)"},"requestedOn":{"type":"string","format":"date-time","description":"Request creation date"},"processingOn":{"type":"string","format":"date-time","description":"Processing start date"},"succeededOn":{"type":"string","format":"date-time","description":"Completion date"},"requestTypeId":{"type":"integer","description":"Request type ID (4 = Short)"},"callbackData":{"type":"string","description":"Custom callback data"},"audioUrl":{"type":"string","description":"URL to the audio used for the short"},"videoUrl":{"type":"string","description":"URL to the generated short video (when completed)"},"imageUrl":{"type":"string","description":"URL to the thumbnail image (when completed)"},"audioTitle":{"type":"string","description":"Title of the short video"},"responseText":{"type":"string","description":"Text content used in the short"},"errorOn":{"type":"string","format":"date-time","description":"Error occurrence date (if applicable)"},"errorMessage":{"type":"string","description":"Error message (if applicable)"}}}}}}
```

## The TranscriptLine object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"TranscriptLine":{"type":"object","properties":{"text":{"type":"string","description":"Transcript line text"},"speaker":{"type":"string","description":"Speaker label"},"timestamp":{"type":"array","description":"Start/end time in seconds","items":{"type":"number"}}}}}}}
```

## The ExplainerTranscript object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"ExplainerTranscript":{"type":"object","properties":{"videoId":{"type":"string","description":"Explainer video identifier (request ID)"},"createdOn":{"type":"string","format":"date-time","description":"Transcript creation timestamp"},"transcript":{"type":"array","items":{"$ref":"#/components/schemas/TranscriptLine"}}}},"TranscriptLine":{"type":"object","properties":{"text":{"type":"string","description":"Transcript line text"},"speaker":{"type":"string","description":"Speaker label"},"timestamp":{"type":"array","description":"Start/end time in seconds","items":{"type":"number"}}}}}}}
```

## The Feed object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Feed":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier for the feed"},"name":{"type":"string","description":"Name of the feed"},"token":{"type":"string","description":"Client token (null for public feeds)"},"feedTypeId":{"type":"integer","description":"Type of feed (1 for X/Twitter, 2 for Reddit, 3 for YouTube channel, 4 for RSS, 5 for X News topic)"},"internalId":{"type":"string","description":"Internal identifier for the feed source (username for X, subreddit for Reddit, channel source ID for YouTube)"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"}}}}}}
```

## The FeedSubscription object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"FeedSubscription":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the subscription"},"feedId":{"type":"integer","description":"Identifier of the subscribed feed"},"token":{"type":"string","description":"Token that owns the subscription"},"requestId":{"type":"string","description":"ClientRequest template identifier used for automation"},"createdOn":{"type":"string","format":"date-time","description":"When the subscription was created"},"removedOn":{"type":"string","format":"date-time","nullable":true,"description":"When the subscription was removed, if applicable"},"lastProcessedItemId":{"type":"string","nullable":true,"description":"Identifier of the last feed item processed for this subscription"},"lastProcessedOn":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of the last processed feed item"},"request":{"type":"object","nullable":true,"description":"Snapshot of the underlying template request"}}}}}}
```

## The CreateFeedRequest object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"CreateFeedRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Name of the feed"},"feedTypeId":{"type":"integer","description":"Type of feed (1 for X/Twitter, 2 for Reddit, 3 for YouTube channel, 4 for RSS, 5 for X News topic)"},"internalId":{"type":"string","description":"Internal identifier - Twitter username for X, subreddit name for Reddit (without r/ prefix), topic/search query for X News (feedTypeId=5), feed URL for RSS. For YouTube channels this is populated automatically."},"channel":{"type":"string","description":"(YouTube only) Channel handle, URL, or ID. Either `channel` or `url` may be provided."},"url":{"type":"string","description":"(YouTube only) Channel URL alternative field."}}}}}}
```

## The DeleteFeedRequest object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"DeleteFeedRequest":{"type":"object","required":["id"],"properties":{"id":{"type":"integer","description":"ID of the feed to delete"}}}}}}
```

## The CreatePodcastShowRequest object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"CreatePodcastShowRequest":{"type":"object","required":["name","description","author","link","imageUrl","email"],"properties":{"name":{"type":"string","description":"Podcast show name (displayed on Spotify, Apple Music, etc.)"},"description":{"type":"string","description":"Show description for platform listings and RSS feed"},"author":{"type":"string","description":"Host/author name displayed on podcast platforms"},"link":{"type":"string","format":"uri","description":"Official website URL for the podcast show"},"imageUrl":{"type":"string","format":"uri","description":"URL of the podcast show image/artwork"},"email":{"type":"string","format":"email","description":"Owner email address for RSS feed and platform registration"},"language":{"type":"string","description":"Primary language for generated podcast episodes (defaults to English)"}}}}}}
```

## The PodcastShow object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"PodcastShow":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the podcast show"},"name":{"type":"string","description":"Name of the podcast show (displayed on Spotify, Apple Music, etc.)"},"description":{"type":"string","description":"Description of the podcast show (used in platform listings)"},"author":{"type":"string","description":"Author/host name (displayed on podcast platforms)"},"link":{"type":"string","description":"Website link for the podcast show"},"email":{"type":"string","format":"email","description":"Owner email address (used in RSS feed and platform settings)"},"token":{"type":"string","description":"Client token for authentication"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedOn":{"type":"string","format":"date-time","description":"Last update timestamp"},"rssUrl":{"type":"string","description":"RSS feed URL for automated distribution to Spotify, Apple Music, and other podcast platforms"}}}}}}
```

## The PodcastEpisode object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"PodcastEpisode":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier for the episode"},"podcastId":{"type":"string","description":"ID of the podcast show this episode belongs to"},"requestId":{"type":"string","description":"ID of the client request that created the source audio content"},"title":{"type":"string","description":"Episode title (displayed on podcast platforms)"},"description":{"type":"string","description":"Episode description (displayed on podcast platforms)"},"audioTitle":{"type":"string","description":"Original title from the generated audio content"},"audioUrl":{"type":"string","description":"Direct URL to the episode audio file (MP3 format for platform compatibility)"},"requestedOn":{"type":"string","format":"date-time","description":"When the episode was requested/created"},"succeededOn":{"type":"string","format":"date-time","description":"When the episode processing completed successfully"},"scheduledOn":{"type":"string","format":"date-time","description":"When the episode is scheduled to be published (if scheduled)"},"fileSize":{"type":"integer","description":"Audio file size in bytes (required for RSS enclosure tag)"},"durationSeconds":{"type":"integer","description":"Episode duration in seconds (displayed on podcast platforms)"}}}}}}
```

## The Project object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"Project":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the project (GUID)"},"name":{"type":"string","description":"Name of the project"},"description":{"type":"string","description":"Detailed description of the project"},"url":{"type":"string","description":"Optional URL associated with the project"},"token":{"type":"string","description":"Client token (owner of the project)"},"createdOn":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedOn":{"type":"string","format":"date-time","description":"Last update timestamp"},"active":{"type":"boolean","description":"Whether the project is active"},"imageUrl":{"type":"string","format":"uri","description":"Optional URL of the 200x50 brand image associated with the project"},"textColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"backgroundColor":{"type":"string","nullable":true,"description":"Hex color (e.g."},"brandColor":{"type":"string","nullable":true,"description":"Primary branding accent color applied to overlay shapes when branding is configured"},"accentColor":{"type":"string","nullable":true,"description":"Secondary accent color applied to overlay highlights and subtitles when branding is configured"}}}}}}
```

## The CreateProjectRequest object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"CreateProjectRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Name of the project (max 200 characters)"},"description":{"type":"string","description":"Detailed description of the project. Either description or url must be provided."},"url":{"type":"string","description":"Optional URL to fetch website content for auto-generating description. If provided without a description, AI will generate one."},"imageData":{"type":"string","description":"Optional base64 encoded PNG/JPG representing the project's brand image. The source image must be fully opaque; images containing any fully or partially transparent pixels are rejected. Any dimensions are accepted and the API resizes the image to 200x50 before storing the hosted copy as `imageUrl`."},"imageUrl":{"type":"string","format":"uri","description":"Optional HTTP/HTTPS URL to an existing PNG or JPG brand image. The source image must be fully opaque; images containing any fully or partially transparent pixels are rejected. The API downloads the source, resizes it to 200x50, and hosts the optimized copy. Cannot be combined with `imageData`."},"textColor":{"type":"string","description":"Optional hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"backgroundColor":{"type":"string","description":"Optional hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"brandColor":{"type":"string","description":"Optional primary accent hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"accentColor":{"type":"string","description":"Optional secondary accent hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"}}}}}}
```

## The UpdateProjectRequest object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"UpdateProjectRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Updated name of the project (max 200 characters)"},"description":{"type":"string","description":"Updated description of the project. Either description or url must be provided."},"url":{"type":"string","description":"Optional URL to fetch website content for auto-generating description. If provided without a description, AI will generate one."},"imageData":{"type":"string","nullable":true,"description":"Optional base64 encoded PNG/JPG. Provide `null` to remove the current brand image. The source image must be fully opaque; images containing any fully or partially transparent pixels are rejected. Any size is accepted and will be resized to 200x50 on upload."},"imageUrl":{"type":"string","nullable":true,"format":"uri","description":"Optional HTTP/HTTPS URL pointing to a PNG or JPG brand image. Provide `null` to remove the stored image. The source image must be fully opaque; images containing any fully or partially transparent pixels are rejected. The API stores a 200x50 version. Cannot be combined with `imageData`."},"textColor":{"type":"string","nullable":true,"description":"Optional hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"backgroundColor":{"type":"string","nullable":true,"description":"Optional hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"brandColor":{"type":"string","nullable":true,"description":"Optional primary accent hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"},"accentColor":{"type":"string","nullable":true,"description":"Optional secondary accent hex color (format","pattern":"^#[0-9A-Fa-f]{6}$"}}}}}}
```

## The XPost object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"XPost":{"type":"object","properties":{"id":{"type":"string","description":"Unique ID of the post (use this for refinement)"},"requestId":{"type":"string"},"result":{"type":"string","description":"The generated content or metadata"},"type":{"type":"string","description":"The post type (e.g., tweet or thread item)"},"order":{"type":"integer","description":"Order in the thread (starts at 0)"},"createdOn":{"type":"string","format":"date-time"},"tweetImageUrl":{"type":"string","nullable":true,"description":"Main image for the tweet (from user upload or provided URL)"},"dataTableImageUrl":{"type":"string","nullable":true,"description":"Optional URL to a generated data table image"},"barChartImageUrl":{"type":"string","nullable":true,"description":"Optional URL to a generated bar chart image"},"sources":{"type":"array","description":"Provenance entries describing where the content came from","items":{"$ref":"#/components/schemas/XPostSource"}},"shareUrl":{"type":"string","description":"Share URL for the post (only in getPodcasts response)"}}},"XPostSource":{"type":"object","properties":{"type":{"type":"string","description":"Classification of the source (e.g. feed, resource, deep-research)"},"sourceId":{"type":"string","nullable":true,"description":"Optional identifier for the source record"},"reference":{"type":"string","nullable":true,"description":"User-friendly reference like a URL or handle"},"description":{"type":"string","nullable":true,"description":"Short summary of the source content"},"metadata":{"type":"object","nullable":true,"additionalProperties":true,"description":"Arbitrary metadata captured for the source"}}}}}}
```

## The XPostSource object

```json
{"openapi":"3.0.0","info":{"title":"Content API","version":"1.0.0"},"components":{"schemas":{"XPostSource":{"type":"object","properties":{"type":{"type":"string","description":"Classification of the source (e.g. feed, resource, deep-research)"},"sourceId":{"type":"string","nullable":true,"description":"Optional identifier for the source record"},"reference":{"type":"string","nullable":true,"description":"User-friendly reference like a URL or handle"},"description":{"type":"string","nullable":true,"description":"Short summary of the source content"},"metadata":{"type":"object","nullable":true,"additionalProperties":true,"description":"Arbitrary metadata captured for the source"}}}}}}
```


# Private Notebooks

Private Notebooks gives you a dedicated notebook account for keeping reusable sources, asking grounded questions with citations, and generating finished assets from the same source workspace.

The subscription is **€99 per month**. One license provides one dedicated notebook account and is activated within one business day after payment. Private Notebook operations do not consume AutoContent API credits; the subscription limits below apply instead.

{% hint style="warning" %}
Private Notebooks is an independent AutoContent API service. It is not provided, sponsored, endorsed, or officially affiliated with Google or NotebookLM. Notebook content, prompts, and generated outputs are processed by third-party AI and platform providers to fulfill requests. Only send content you are authorized to process, and account for this processing in your privacy notices.
{% endhint %}

## Authentication and Idempotency

Use your AutoContent API token on every request:

```http
Authorization: Bearer YOUR_API_TOKEN
```

An active Private Notebooks license is required. A notebook belongs to the customer that created it; another customer cannot read, change, query, or delete that notebook ID.

Every operation that changes state or asks a question also requires an `Idempotency-Key` header:

```http
Idempotency-Key: pn-create-018f4f6e-23b1-7ef1-a867-acde48001122
```

Use an opaque printable ASCII value between 8 and 192 characters. Keep the same key when retrying the same operation. Reusing it with different input returns `409 Conflict`.

The header is required for:

* `POST /dedicated-account/notebooks`
* `DELETE /dedicated-account/notebooks/:notebookId`
* `POST /dedicated-account/notebooks/:notebookId/sources`
* `POST /dedicated-account/notebooks/:notebookId/questions`
* `POST /Content/Create` when the body contains `notebookId`

It is not required for the `GET` endpoints.

## Endpoints

| Method   | Endpoint                                             | Purpose                                                  |
| -------- | ---------------------------------------------------- | -------------------------------------------------------- |
| `POST`   | `/dedicated-account/notebooks`                       | Create a notebook, optionally with initial sources       |
| `GET`    | `/dedicated-account/notebooks`                       | List your notebooks                                      |
| `GET`    | `/dedicated-account/notebooks/:notebookId`           | Get one owned notebook                                   |
| `DELETE` | `/dedicated-account/notebooks/:notebookId`           | Delete one owned notebook and its sources                |
| `POST`   | `/dedicated-account/notebooks/:notebookId/sources`   | Add sources to an owned notebook                         |
| `POST`   | `/dedicated-account/notebooks/:notebookId/questions` | Ask a grounded question                                  |
| `GET`    | `/dedicated-account/usage`                           | Read capacity and current rolling 24-hour usage          |
| `POST`   | `/Content/Create`                                    | Generate an asset from an owned notebook's saved sources |
| `GET`    | `/Content/Status/:requestId`                         | Poll a generated asset until it completes                |

Individual source deletion is not supported. Delete the notebook when all of its sources should be removed.

## Supported Sources

Each source has a `type`, `content`, and, for uploaded files, an optional `fileName`.

| Type      | `content`                 | Notes                                           |
| --------- | ------------------------- | ----------------------------------------------- |
| `text`    | Plain text                | Up to 500,000 characters                        |
| `website` | An `http` or `https` URL  | The provider reads the page                     |
| `youtube` | A YouTube URL             | `youtube.com` and `youtu.be` URLs are accepted  |
| `pdf`     | Base64-encoded PDF bytes  | Up to 50 MB; a base64 data URL is also accepted |
| `file`    | Base64-encoded file bytes | Up to 50 MB; include `fileName`                 |

`file` accepts `.pdf`, `.txt`, `.md`, `.csv`, `.docx`, `.pptx`, `.xlsx`, `.mp3`, `.wav`, `.m4a`, `.png`, `.jpg`, `.jpeg`, and `.webp` files.

## Create a Notebook with cURL

Creating a notebook may include an empty `sources` array or up to 20 initial sources. Add more in batches of 20 until the notebook reaches its 100-source capacity:

```bash
curl -X POST "https://api.autocontentapi.com/dedicated-account/notebooks" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Idempotency-Key: pn-create-018f4f6e-23b1-7ef1-a867-acde48001122" \
  -H "Content-Type: application/json" \
  -d '{
    "sources": [
      {
        "type": "text",
        "content": "Our annual plan includes priority support and unlimited team seats."
      },
      {
        "type": "website",
        "content": "https://example.com/product"
      }
    ]
  }'
```

A new request returns `201 Created`:

```json
{
  "notebookId": "provider-notebook-id",
  "sourceCount": 2,
  "sources": [
    {
      "index": 0,
      "success": true,
      "sourceId": "source-record-id-1"
    },
    {
      "index": 1,
      "success": true,
      "sourceId": "source-record-id-2"
    }
  ],
  "replay": false
}
```

An idempotent replay returns `200 OK` with `replay: true`. Source ingestion can partially succeed, so inspect every item in `sources` even when the HTTP request succeeds. A failed item has `success: false` and an `errorMessage`.

## Add a PDF Source

Base64-encode the file bytes and send them as `content`:

```bash
curl -X POST "https://api.autocontentapi.com/dedicated-account/notebooks/NOTEBOOK_ID/sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Idempotency-Key: pn-source-018f4f76-6ac8-7b17-bbf8-acde48001122" \
  -H "Content-Type: application/json" \
  -d '{
    "sources": [
      {
        "type": "pdf",
        "fileName": "annual-report.pdf",
        "content": "JVBERi0xLjcK..."
      }
    ]
  }'
```

The response identifies the result for each submitted source:

```json
{
  "notebookId": "NOTEBOOK_ID",
  "sources": [
    {
      "index": 0,
      "success": true,
      "sourceId": "source-record-id-3"
    }
  ],
  "replay": false
}
```

## Ask a Question and Read Citations

Questions can contain up to 5,000 characters:

```bash
curl -X POST "https://api.autocontentapi.com/dedicated-account/notebooks/NOTEBOOK_ID/questions" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Idempotency-Key: pn-question-018f4f8b-8591-7c5f-98ea-acde48001122" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What are the main findings and which sources support them?"
  }'
```

`citations` is an object keyed by the citation marker used in the answer:

```json
{
  "notebookId": "NOTEBOOK_ID",
  "answer": "The report identifies three main findings.[1]",
  "citations": {
    "1": {
      "citationDocument": "annual-report.pdf",
      "citationTitle": "1",
      "citationText": "Relevant source excerpt"
    }
  },
  "replay": false,
  "usage": {
    "used": 17,
    "limit": 200,
    "resetsOn": "2026-08-16T09:42:31.000Z"
  }
}
```

Citation fields depend on the underlying source and may be empty. Treat the `citations` keys as strings and render only citations returned by the API.

## Licensed Generation Capacity

Every notebook-bound generation runs on the same dedicated account assigned to your license. It uses the notebook's existing sources, does not consume AutoContent generation credits, and never rotates through the shared account pool.

The supported `outputType` values are:

* `audio`
* `video`
* `text`
* `faq`
* `study_guide`
* `timeline`
* `briefing_doc`
* `quiz`
* `infographic`
* `slide_deck`
* `datatable`

Submit the job through `/Content/Create` with the owned `notebookId`, then poll `/Content/Status/:requestId` exactly as you would for other AutoContent jobs. Do not add `resources`, `topic`, `projects`, feeds, research IDs, channels, or episode IDs to a notebook-bound request. Add sources to the notebook first so the persistent source workspace remains the only generation context.

```bash
curl -X POST https://api.autocontentapi.com/Content/Create \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pn-asset-018f4f6e-23b1-7ef1-a867-acde48001122" \
  -d '{
    "notebookId": "NOTEBOOK_ID",
    "outputType": "infographic",
    "language": "English"
  }'
```

The create response contains `request_id`. Poll its status until `status` is `100`. Depending on the output, the terminal response contains grounded `response_text` and citations, or a downloadable field such as `audio_url`, `video_url`, `image_url`, `briefing_doc_url`, `slide_deck_url`, or `datatable_url`. Replaying the same request with the same idempotency key returns the same request ID and does not submit a second provider generation.

## Node.js Example

This example creates a notebook and asks it a question using the built-in `fetch` available in Node.js 18 and later:

```javascript
import { randomUUID } from 'node:crypto';

const baseUrl = 'https://api.autocontentapi.com';
const token = process.env.AUTOCONTENT_API_TOKEN;

async function api(path, options = {}) {
  const response = await fetch(`${baseUrl}${path}`, {
    ...options,
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
      ...options.headers
    }
  });
  const body = await response.json();
  if (!response.ok) throw new Error(`${response.status}: ${JSON.stringify(body)}`);
  return body;
}

const created = await api('/dedicated-account/notebooks', {
  method: 'POST',
  headers: { 'Idempotency-Key': `create-${randomUUID()}` },
  body: JSON.stringify({
    sources: [{ type: 'text', content: 'Revenue grew 24% year over year.' }]
  })
});

const result = await api(
  `/dedicated-account/notebooks/${encodeURIComponent(created.notebookId)}/questions`,
  {
    method: 'POST',
    headers: { 'Idempotency-Key': `question-${randomUUID()}` },
    body: JSON.stringify({ question: 'How much did revenue grow?' })
  }
);

console.log(result.answer);
console.log(result.citations);
```

## Python Example

This example creates an empty notebook, uploads a PDF, and asks a question. Install the `requests` package first.

```python
import base64
import os
import uuid
from pathlib import Path

import requests

BASE_URL = "https://api.autocontentapi.com"
TOKEN = os.environ["AUTOCONTENT_API_TOKEN"]


def post(path, payload, operation):
    response = requests.post(
        f"{BASE_URL}{path}",
        headers={
            "Authorization": f"Bearer {TOKEN}",
            "Idempotency-Key": f"{operation}-{uuid.uuid4()}",
        },
        json=payload,
        timeout=120,
    )
    response.raise_for_status()
    return response.json()


notebook = post(
    "/dedicated-account/notebooks",
    {"sources": []},
    "create",
)
notebook_id = notebook["notebookId"]

pdf_bytes = Path("annual-report.pdf").read_bytes()
post(
    f"/dedicated-account/notebooks/{notebook_id}/sources",
    {
        "sources": [
            {
                "type": "pdf",
                "fileName": "annual-report.pdf",
                "content": base64.b64encode(pdf_bytes).decode("ascii"),
            }
        ]
    },
    "source",
)

answer = post(
    f"/dedicated-account/notebooks/{notebook_id}/questions",
    {"question": "Summarize the report's main risks."},
    "question",
)
print(answer["answer"])
print(answer["citations"])
```

In production, retain each idempotency key with its operation so a network retry sends the same key instead of generating a new one.

## List, Read, Delete, and Check Usage

These examples use the same Bearer token. Only deletion needs an idempotency key.

```bash
# List notebooks
curl "https://api.autocontentapi.com/dedicated-account/notebooks" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Get one notebook
curl "https://api.autocontentapi.com/dedicated-account/notebooks/NOTEBOOK_ID" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Check usage and limits
curl "https://api.autocontentapi.com/dedicated-account/usage" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Delete a notebook and all of its sources
curl -X DELETE "https://api.autocontentapi.com/dedicated-account/notebooks/NOTEBOOK_ID" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Idempotency-Key: pn-delete-018f4fc2-0621-72f7-b095-acde48001122"
```

The list response wraps records in `notebooks`; the single-notebook response returns one record directly:

```json
{
  "notebooks": [
    {
      "notebookId": "NOTEBOOK_ID",
      "sourceCount": 3,
      "createdOn": "2026-08-15T08:30:00.000Z",
      "updatedOn": "2026-08-15T09:15:00.000Z"
    }
  ]
}
```

A successful deletion returns `success: true`, the deleted `notebookId`, and a `replay` flag.

Usage response:

```json
{
  "window": "rolling_24_hours",
  "windowStart": "2026-08-14T10:00:00.000Z",
  "observedOn": "2026-08-15T10:00:00.000Z",
  "usage": {
    "questions": { "used": 17, "limit": 200, "resetsOn": "2026-08-16T09:42:31.000Z" },
    "audio": { "used": 0, "limit": 6, "resetsOn": null },
    "video": { "used": 0, "limit": 6, "resetsOn": null },
    "reports": { "used": 0, "limit": 20, "resetsOn": null },
    "quizzes": { "used": 0, "limit": 20, "resetsOn": null }
  },
  "capacity": {
    "notebooks": 200,
    "sourcesPerNotebook": 100
  }
}
```

## Plan Limits

| Capability                                             |                                                 Limit |
| ------------------------------------------------------ | ----------------------------------------------------: |
| Dedicated accounts per license                         |                                                     1 |
| Notebooks                                              |                                                   200 |
| Sources per notebook                                   |                                                   100 |
| Grounded questions                                     |                          200 after each 24-hour reset |
| Audio overview account capacity                        |                            6 after each 24-hour reset |
| Video overview account capacity                        |                            6 after each 24-hour reset |
| Reports: FAQ, study guide, timeline, briefing document |                           20 after each 24-hour reset |
| Quizzes                                                |                           20 after each 24-hour reset |
| Infographics, slide decks, and data tables             | Provider-governed capacity; no invented numeric limit |

`text` generation uses the same question allowance as the direct questions endpoint. All listed output request and retrieval paths have been verified end to end. Upstream capacity can still change, and the API returns a clear provider error if the assigned account reaches a provider limit that has no published numeric allowance.

Google's published help says daily quotas reset after 24 hours but does not expose an account reset timestamp to this API. AutoContent therefore applies a conservative rolling 24-hour admission window and also surfaces upstream quota errors. Use `GET /dedicated-account/usage` instead of calculating availability locally; each used capability includes its next local `resetsOn` timestamp.

## Error Handling

| Status | Meaning                                                                                                      | Recommended action                                                                                                    |
| -----: | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
|  `400` | Invalid body, source, notebook ID, question, or idempotency key                                              | Correct the request before retrying                                                                                   |
|  `401` | Missing or invalid Bearer token                                                                              | Supply a valid AutoContent API token                                                                                  |
|  `403` | No active Private Notebooks license                                                                          | Wait for activation or restore the subscription                                                                       |
|  `404` | Notebook not found or not owned by the authenticated customer                                                | Verify the notebook ID and token                                                                                      |
|  `409` | The key was reused with different input, work is already in flight, or the prior mutation must be reconciled | If `Retry-After` is present, wait and retry the identical request with the same key; otherwise inspect the error code |
|  `429` | Notebook/source capacity or a rolling 24-hour allowance was reached                                          | Read `/dedicated-account/usage` and wait until `resetsOn` when applicable                                             |
|  `503` | The service, dedicated account, or third-party provider is temporarily unavailable                           | Retry the identical request with the same key and exponential backoff                                                 |

Private Notebook endpoints commonly return `error`, `errorMessage`, and optional `details`. Managed mutation conflicts may instead include `success: false`, `code`, and `error`. Parse the HTTP status first and preserve these fields in logs.


# Quick Start

Pick a content type to open its starter guide and jump straight into examples.

## 🎙️ Podcasts

Launch RSS-ready episodes from feeds, research, or scripts.

* Start with [Create a Podcast Episode](/quick-start/podcasts/create-podcast-episode)
* Examples: [Podcast Scenario Examples](/quick-start/podcasts/podcast-examples)
* Variations: [Create a Podcast from X Feed](/quick-start/podcasts/create-feed-podcast), [Create a Podcast from Deep Research](/quick-start/deep-researches/create-research-podcast)

## 🎬 Explainer Videos

Turn research links, PDFs, or scripts into narrated motion graphics.

* Start with [Create an Explainer Video](/quick-start/explainer-videos/create-explainer-video)
* Examples: [Explainer Video Scenario Examples](/quick-start/explainer-videos/explainer-video-examples)

## 🖼️ Infographics

Generate visual one-pagers with `outputType: "infographic"` and control `infographicOrientation` or `infographicDetail`.

* Start with [Create an Infographic from Text](/quick-start/infographics/from-text)
* Examples: [Infographic Scenario Examples](/quick-start/infographics/infographic-examples)

## 📄 Documents

Generate briefing documents with `outputType: "briefing_doc"` and choose whether the final artifact should be `text`, `html`, or `pdf`.

* Start with [Create a Briefing Document](/quick-start/documents/create-document)
* Examples: [Document Scenario Examples](/quick-start/documents/document-examples)

## 🧪 Quizzes

Generate assessments with `outputType: "quiz"` and set `quizDifficulty` (`easy`, `medium`, `hard`).

* Start with [Create a Quiz from Text](/quick-start/quizzes/from-text)
* Examples: [Quiz Scenario Examples](/quick-start/quizzes/quiz-examples)

## 📊 Data Tables

Generate spreadsheet-ready tables with `outputType: "datatable"`, poll the shared status endpoint, and download the completed spreadsheet from `/data-tables/{id}/download`.

* Start with [Create a Data Table](/quick-start/data-tables/create-data-table)
* Examples: [Data Table Scenario Examples](/quick-start/data-tables/data-table-examples)

## 🗂️ Slide Decks

Build slideware by switching to `outputType: "slide_deck"` and choosing `slideDeckFormat` (`detailed` or `presenter`).

* Start with [Create a Slide Deck from Text](/quick-start/slide-decks/from-text)
* Examples: [Slide Deck Scenario Examples](/quick-start/slide-decks/slide-deck-examples)

## 📱 Video Shorts

Produce avatar-led shorts for social clips and explainers.

* Start with [Create a Video Short](/quick-start/video-shorts/create-video-short)
* Examples: [Alternative Methods](/quick-start/video-shorts/create-video-short#alternative-methods) for audio, scripts, and deep research inputs

## 🔬 Deep Researches

Collect long-form analyses you can reuse across podcasts, decks, and infographics.

* Start with [Start Deep Research](/quick-start/deep-researches/start-deep-research)
* Examples: [Create a Podcast Episode from Deep Research](/quick-start/deep-researches/create-research-podcast)

## 🛠️ Tools

Handle the supporting workflows around uploads, request tracking, voice cloning, and transcription.

* Track async jobs with [Track Requests & Status Codes](/quick-start/tools/track-requests)
* Upload private PDFs via [Upload Private Files](/quick-start/tools/upload-files)
* Clone custom narration with [Clone a Voice](/quick-start/tools/clone-voice)
* Turn audio into text with [Transcribe Audio](/quick-start/tools/transcribe-audio)

## Branding & Projects

Save reusable logos and color palettes to apply across outputs.

* Start with [Create a Project (Brand Assets)](/quick-start/tools/create-project)


# Podcasts


# Create a Podcast Episode

Generate your first AI-powered podcast episode in just a few simple steps. This guide will walk you through creating a podcast from web resources and retrieving the generated audio.

## Step 1: Create Content Request

Send a POST request to `/content/create` with your resources and specify `audio` as the output type:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "resources": [
      {
        "type": "website",
        "content": "https://example.com/article-about-ai"
      },
      {
        "type": "youtube", 
        "content": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
      }
    ],
    "outputType": "audio",
    "text": "Create an engaging podcast discussion about AI developments",
    "duration": "long"
  }'
```

### Example Response

```json
{
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0
}
```

**Important:** Save the `request_id` - you'll need it to check the status and retrieve your audio!

## Step 2: Poll for Status

Use the `request_id` to check the processing status by calling `/content/Status/{id}`:

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### While Processing

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 5,
  "updated_on": "2024-01-15T10:32:00Z",
  "error_code": 0,
  "requested_on": "2024-01-15T10:30:00Z"
}
```

**Status Codes:**

* `0` = Pending (queued for processing)
* `5` = Processing (generation in progress)
* `100` = Completed (audio ready!)

## Step 3: Get Your Audio

When `status` reaches `100`, the response includes your generated audio:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "audio_title": "AI Developments Discussion",
  "status": 100,
  "audio_url": "https://storage.autocontentapi.com/audio/550e8400-e29b-41d4-a716-446655440000.mp3",
  "response_text": "Full transcript of the generated podcast...",
  "requested_on": "2024-01-15T10:30:00Z",
  "updated_on": "2024-01-15T10:35:00Z",
  "request_type_id": 1,
  "error_code": 0,
  "file_size": 15234567,
  "audio_duration": 456.78,
  "share_url": "https://autocontentapi.com/share/550e8400-e29b-41d4-a716-446655440000"
}
```

**🎉 Success!** Your podcast is ready at the `audio_url`!

## Resource Types

You can use different types of resources in your request:

| Type      | Description         | Example                                      |
| --------- | ------------------- | -------------------------------------------- |
| `website` | Any web page URL    | `"https://techcrunch.com/article"`           |
| `youtube` | YouTube video URL   | `"https://www.youtube.com/watch?v=VIDEO_ID"` |
| `text`    | Direct text content | `"Your custom instructions or content"`      |
| `pdf`     | PDF document URL    | `"https://example.com/document.pdf"`         |

## Duration Options

Control the length of your generated podcast:

* `"short"` - 3-5 minutes
* `"default"` - 8-12 minutes
* `"long"` - 15-20 minutes

> Need a specific payload? Check the new [Podcast Scenario Examples](/quick-start/podcasts/podcast-examples) for copy-paste `curl` requests covering languages, durations, styles, and every supported resource type.

## Tips for Better Results

1. **Mix resource types** - Combine websites, videos, and text for richer content
2. **Provide clear instructions** - Use the `text` field to guide the conversation
3. **Check status regularly** - Processing typically takes 2-5 minutes
4. **Save the request\_id** - You'll need it to retrieve your audio

## Error Handling

If something goes wrong, the status response will include error details:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0,
  "error_code": 400,
  "error_message": "Invalid resource URL provided",
  "requested_on": "2024-01-15T10:30:00Z"
}
```

## What's Next?

* 📡 Publish episodes via [Create a Podcast Show](/quick-start/podcasts/create-podcast-show)
* 🎙️ Create custom hosts with [Clone a Voice](/quick-start/tools/clone-voice)
* 📝 Turn finished audio into transcripts with [Transcribe Audio](/quick-start/tools/transcribe-audio)
* 📖 Explore more [Code Samples](/code-samples) in different languages
* 🗣️ Learn about [Custom Voices](/voices) for personalized podcasts
* 🔮 Check out [Advanced Integrations](/integrations)
* ❓ Have questions? Visit our [FAQ](/faq)


# Create a Podcast from X Feed

Learn how to create a feed from an X (Twitter) account and use it to generate AI-powered podcast content from the latest posts.

> Building feeds through the dashboard first? Follow [Create a Feed](/quick-start/podcasts/create-feed) for the in-app workflow and then return here for the raw API calls.

## Step 1: Create an X Feed

First, create a feed from an X account by sending a POST request to `/feeds`:

```bash
curl -X POST "https://api.autocontentapi.com/feeds" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Tech News from Elon Musk",
    "feedTypeId": 1,
    "internalId": "elonmusk"
  }'
```

### Request Parameters

| Parameter    | Description                | Example                      |
| ------------ | -------------------------- | ---------------------------- |
| `name`       | Display name for your feed | `"Tech News from Elon Musk"` |
| `feedTypeId` | Feed type (1 = X/Twitter)  | `1`                          |
| `internalId` | X username (without @)     | `"elonmusk"`                 |

### Example Response

```json
{
  "success": true,
  "feedId": 42,
  "message": "Feed created successfully"
}
```

**Important:** Save the `feedId` - you'll use it to generate podcasts from this feed!

## Step 2: List Recent Feed Items

Fetch cached items for the feed:

```bash
curl -X GET "https://api.autocontentapi.com/feeds/42/items" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

Example response:

```json
{
  "feed": {
    "id": 42,
    "name": "Tech News from Elon Musk",
    "feedTypeId": 1
  },
  "items": [
    {
      "identifier": "1876982459012345678",
      "content": "Mars launch update...",
      "resourceType": "text",
      "resourceValue": "Mars launch update..."
    },
    {
      "identifier": "1876982459012345679",
      "content": "New AI product announcement...",
      "resourceType": "text",
      "resourceValue": "New AI product announcement..."
    }
  ]
}
```

Save the item `identifier` values you want to include.

## Step 3: Create Podcast from Selected Feed Items

Use `feedSelections` to generate a podcast from specific cached posts:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "feedSelections": [
      {
        "feedId": 42,
        "feedItemIds": ["1876982459012345678", "1876982459012345679"]
      }
    ],
    "text": "Create an engaging podcast discussing the latest tweets and their implications",
    "duration": "default"
  }'
```

### Example Response

```json
{
  "request_id": "feed-550e8400-e29b-41d4-a716-446655440001",
  "status": 0
}
```

## Step 4: Poll for Status

Use the `request_id` to check processing status:

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/feed-550e8400-e29b-41d4-a716-446655440001" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### While Processing

```json
{
  "id": "feed-550e8400-e29b-41d4-a716-446655440001",
  "status": 5,
  "updated_on": "2024-01-15T10:32:00Z",
  "error_code": 0,
  "requested_on": "2024-01-15T10:30:00Z"
}
```

## Step 5: Get Your Feed-Based Podcast

When `status` reaches `100`, your podcast is ready:

```json
{
  "id": "feed-550e8400-e29b-41d4-a716-446655440001",
  "audio_title": "Latest Updates from Tech Leaders",
  "status": 100,
  "audio_url": "https://storage.autocontentapi.com/audio/feed-550e8400-e29b-41d4-a716-446655440001.mp3",
  "response_text": "Full transcript discussing the latest posts from the feed...",
  "requested_on": "2024-01-15T10:30:00Z",
  "updated_on": "2024-01-15T10:35:00Z",
  "request_type_id": 1,
  "error_code": 0,
  "file_size": 18734521,
  "audio_duration": 567.89,
  "share_url": "https://autocontentapi.com/share/feed-550e8400-e29b-41d4-a716-446655440001"
}
```

## Managing Your Feeds

### List All Your Feeds

```bash
curl -X GET "https://api.autocontentapi.com/feeds" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Get Specific Feed Details

```bash
curl -X GET "https://api.autocontentapi.com/feeds/42" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Delete a Feed

```bash
curl -X POST "https://api.autocontentapi.com/feeds/delete" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 42
  }'
```

## Advanced: Multiple Feed Selections

You can combine selected items from multiple feeds in a single podcast request:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "feedSelections": [
      {
        "feedId": 42,
        "feedItemIds": ["1876982459012345678"]
      },
      {
        "feedId": 43,
        "feedItemIds": ["post_abc123", "post_def456"]
      }
    ],
    "text": "Create a podcast discussing the latest posts from these tech leaders",
    "duration": "long"
  }'
```

**Note:** Maximum of 10 feed groups per request and 50 item IDs per feed group.

## Feed Limitations

* **Feed Limit:** Your plan controls how many feeds/channels you can create
* **Rate Limiting:** Wait 3 seconds between feed creation requests
* **Feed Types:** `1` = X/Twitter, `2` = Reddit, `3` = YouTube channel, `4` = RSS, `5` = X News topic
* **Username Format:** For X feeds, use the username without the @ symbol

## Popular X Accounts for Tech Feeds

Here are some popular tech accounts you might want to create feeds from:

| Username       | Description                 |
| -------------- | --------------------------- |
| `elonmusk`     | Tesla/SpaceX CEO insights   |
| `sundarpichai` | Google CEO updates          |
| `satyanadella` | Microsoft CEO thoughts      |
| `tim_cook`     | Apple CEO announcements     |
| `jeffbezos`    | Amazon founder perspectives |
| `naval`        | Startup and tech philosophy |
| `balajis`      | Crypto and tech trends      |

## Error Handling

### Feed Creation Errors

```json
{
  "success": false,
  "error": "Feed limit reached. You can create up to 4 feeds. You currently have 4 feeds."
}
```

### Rate Limit Error

```json
{
  "success": false,
  "error": "Rate limit exceeded. Please wait 3 seconds before creating another feed."
}
```

## Use Cases

**Daily Tech Briefings:** Create feeds from multiple tech leaders and generate daily summary podcasts

**Industry Analysis:** Follow specific industry accounts and create weekly analysis podcasts

**Event Coverage:** Create temporary feeds during conferences or product launches

**Competitor Monitoring:** Track competitor announcements and create regular update podcasts

## What's Next?

* 🎧 Learn about [Creating Basic Podcasts](/quick-start/podcasts/create-podcast-episode) from web resources
* 📖 Explore more [Code Samples](/code-samples) in different languages
* 🗣️ Discover [Custom Voices](/voices) for personalized feed podcasts
* ❓ Have questions? Visit our [FAQ](/faq)


# Create a Podcast Show

Launch a dedicated podcast show inside the AutoContent app, generate a platform-ready RSS feed, and keep episodes in sync across Spotify, Apple Podcasts, and every other directory.

## Before You Begin

* Add your API key under `Settings` so the Shows pages can authenticate requests.
* Record at least one finished episode (see [Create a Podcast Episode](/quick-start/podcasts/create-podcast-episode)) if you plan to populate the RSS feed immediately.
* Prepare square cover art (minimum 1400x1400 px, max 10 MB, JPG/PNG).

## Step 1: Open the Shows Dashboard

1. In the sidebar, go to `Podcasts → Shows`.
2. Click `Create Show` to open the dedicated creation form (`/podcasts/shows/create`).

The page splits into an editor on the left and a live list of your existing shows on the right so you can reuse details or confirm RSS links while you work.

## Step 2: Complete Show Details

Fill in the required metadata exactly as streaming directories expect:

| Field        | Required | Notes                                                        |
| ------------ | -------- | ------------------------------------------------------------ |
| Podcast Name | ✅        | Appears as the show title everywhere your RSS is submitted.  |
| Host         | ✅        | Credited host/author for platform listings.                  |
| Website Link | ✅        | Landing page for listeners; must be a valid URL.             |
| Owner Email  | ✅        | Used by Apple Podcasts and others for feed ownership checks. |
| Description  | ✅        | Long-form summary for directory previews.                    |

Tip: Hover the `ℹ️` icons next to the email and image labels for quick reminders of the publishing requirements directly in the app.

## Step 3: Add Cover Art

Choose how you want to supply the artwork:

* **Image URL** – Paste a public link to centrally hosted artwork. Ideal if design lives in a CMS.
* **Upload File** – Switch to the `Upload` tab and attach a local JPG/PNG under 10 MB. The app automatically switches to the multipart endpoint.

If the artwork fails validation (wrong MIME type, oversize), the form surfaces the exact issue so you can correct it before resubmitting.

## Step 4: Create the Show

Click `Create Podcast Show`. On success the UI flashes a confirmation banner and writes the new feed into the list on the right with its generated RSS URL. That URL is what you submit to external distributors.

Want to automate the same call? Toggle "Show API Request" above the submit button to reveal the exact payload. The underlying requests look like this:

```bash
# JSON payload with hosted artwork
curl -X POST "https://api.autocontentapi.com/podcast/shows" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Podcast Show",
    "description": "A weekly breakdown of the most interesting tech stories.",
    "author": "Alex Rivera",
    "link": "https://example.com/podcast",
    "email": "podcast@example.com",
    "imageUrl": "https://cdn.example.com/podcast/artwork-1400.jpg"
  }'
```

```bash
# Multipart upload when you provide a local file
curl -X POST "https://api.autocontentapi.com/podcast/shows/with-image" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "name=My Podcast Show" \
  -F "description=A weekly breakdown of the most interesting tech stories." \
  -F "author=Alex Rivera" \
  -F "link=https://example.com/podcast" \
  -F "email=podcast@example.com" \
  -F "imageFile=@/path/to/cover.jpg"
```

The API responds with:

```json
{
  "success": true,
  "rssUrl": "https://rss.autocontentapi.com/podcast/abcd1234.xml"
}
```

## Step 5: Manage Shows and Distribution

Return to `Podcasts → Shows` any time to:

* Copy the RSS feed (`Copy RSS` action) for instant submission to Spotify, Apple Podcasts, Google Podcasts, etc.
* Jump to the public site via the `Website` shortcut if you stored a landing page.
* Download a CSV of attached episodes for reporting.
* Delete a show (requires confirmation) or import an external RSS feed when migrating from another host.
* Filter the episode board by clicking a show card—the app opens `Podcasts → Episodes` scoped to that show.

## Step 6: Publish Episodes into the Show

When you generate or edit an episode (`Podcasts → Episodes → New Episode`), use the `Podcast Show` dropdown to attach the request ID to the show you just created. Once the episode finishes, the RSS feed updates automatically and syndicates everywhere you submitted it.

Need a refresher on episode creation? Follow [Create a Podcast Episode](/quick-start/podcasts/create-podcast-episode). Scheduling a release or tweaking voices is covered under [Podcast Scenario Examples](/quick-start/podcasts/podcast-examples).

## Related Endpoints

* `GET /podcast/shows` – List all shows with IDs, metadata, and RSS URLs.
* `POST /podcast/shows` – Create with a hosted image.
* `POST /podcast/shows/with-image` – Create while uploading artwork.
* `POST /podcast/remove` – Delete a show by ID.
* `POST /podcast/import-rss` – Import an existing feed into the dashboard.

## What's Next?

* Attach fresh audio by following [Create a Podcast Episode](/quick-start/podcasts/create-podcast-episode).
* Schedule future drops with the [Scheduler](/quick-start/podcasts/set-duration).
* Connect deep research outputs by learning how to [Start Deep Research](/quick-start/deep-researches/start-deep-research).


# Create a Feed

Capture posts from social sources once and reuse them for podcasts, schedules, and social reposts inside AutoContent.

## Before You Begin

* Add your API key in `Settings`; the Feeds pages stay locked until authentication succeeds.
* Decide which source type you need. Feeds support X/Twitter, Reddit, YouTube channels, RSS URLs, and X News topics.
* Keep the source identifiers handy: X username without `@`, subreddit without `r/`, YouTube channel URL or handle, RSS URL, or X News topic/search query.

## Step 1: Open the Feeds Dashboard

1. In the sidebar, go to `Feeds`.
2. Review any existing feeds grouped by source. Each card shows the most recent refresh time and shortcuts to the original account or subreddit.
3. Click `Create Feed` to launch the builder at `/feeds/create`.

## Step 2: Fill Out Feed Details

The form mirrors the publishing requirements enforced by the API:

| Field      | Required | Notes                                                                                         |
| ---------- | -------- | --------------------------------------------------------------------------------------------- |
| Feed Name  | Yes      | Friendly label that appears in episode and scheduler pickers.                                 |
| Feed Type  | Yes      | `1` = X/Twitter, `2` = Reddit, `3` = YouTube channel, `4` = RSS, `5` = X News topic.          |
| Identifier | Yes      | Use `internalId` for X, Reddit, RSS, and X News. Use `channel` or `url` for YouTube channels. |

Cards highlight the differences between source types. Use the helper text under each field if you forget the exact format.

## Step 3: Create the Feed

Select `Create Feed`. The button locks while the API runs and the success banner reveals the new `Feed ID`. You will also see the feed under the relevant section back on the dashboard.

Need the raw request for automation? Toggle `Show API Request` to view the exact payload the UI sends:

```bash
curl -X POST "https://api.autocontentapi.com/feeds" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Tech News from Elon Musk",
    "feedTypeId": 1,
    "internalId": "elonmusk"
  }'
```

On success the API responds with:

```json
{
  "success": true,
  "feedId": 42,
  "message": "Feed created successfully"
}
```

Other feed type examples:

```json
{
  "name": "AI Product RSS",
  "feedTypeId": 4,
  "internalId": "https://example.com/feed.xml"
}
```

```json
{
  "name": "AutoContent YouTube",
  "feedTypeId": 3,
  "channel": "https://www.youtube.com/@AutoContentAPI"
}
```

```json
{
  "name": "X News: AI",
  "feedTypeId": 5,
  "internalId": "artificial intelligence"
}
```

## Step 4: Manage Feeds from the Dashboard

The `Feeds` page is your control center:

* **View source:** `View Source` opens the original account or subreddit in a new tab.
* **Check freshness:** Each card shows the last update timestamp and relative age (for example, `12m ago`).
* **Delete feed:** Use the `X` button on a card to remove a feed (confirmation required). Your plan controls how many feeds/channels you can keep.
* **Empty state:** If you clear every feed, you will get a guided prompt to create a new one.

## Step 5: Generate Podcasts from Feeds

Feeds become selectable across creation tools:

* In `Podcasts -> Episodes -> New Episode`, choose the `Use Feeds` card, pick one or more feeds, and finish the request. That selection reuses the same flow documented in [Create a Podcast Episode from an X Feed](/quick-start/podcasts/create-feed-podcast).
* In the Scheduler, switch `Input Mode` to `Feeds` to automate recurring drops based on your saved sources.
* When episode generation finishes, attach it to a show via [Create a Podcast Show](/quick-start/podcasts/create-podcast-show) so the RSS feed updates automatically.

For direct API calls, first fetch selectable cached items:

```bash
curl -X GET "https://api.autocontentapi.com/feeds/42/items" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

The response includes the feed and recent items:

```json
{
  "feed": {
    "id": 42,
    "name": "Tech News from Elon Musk",
    "feedTypeId": 1
  },
  "items": [
    {
      "identifier": "1876982459012345678",
      "content": "New product update...",
      "resourceType": "text",
      "resourceValue": "New product update..."
    }
  ]
}
```

Pass selected item `identifier` values through `feedSelections`:

```json
{
  "outputType": "audio",
  "feedSelections": [
    {
      "feedId": 42,
      "feedItemIds": ["1876982459012345678", "1876982459012345679"]
    }
  ],
  "text": "Create a concise news-style podcast from these selected feed items."
}
```

`feedSelections` replaces the older top-level `feeds` array. You can include up to 10 feed groups and up to 50 item IDs per feed group.

## Step 6: Automate Feed Runs

Feed subscriptions watch a feed and create new content as new items arrive.

### Subscribe an Existing Feed Template

Create a reusable template with `/content/Create`:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "templateMode": {
      "type": "feed",
      "name": "Daily AI news digest"
    },
    "text": "Create a five-minute daily digest with the biggest developments and practical takeaways.",
    "duration": "default",
    "style": "deep dive"
  }'
```

The response includes `template_request_id`. Subscribe the feed to that template:

```bash
curl -X POST "https://api.autocontentapi.com/feeds/subscriptions" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "feedId": 42,
    "requestId": "TEMPLATE_REQUEST_ID",
    "intervalMinutes": 1440,
    "digestMode": true
  }'
```

* `intervalMinutes`: Minimum time between automated runs. Omit it to run whenever new items are available.
* `digestMode`: When `true`, the run combines the window of new items into one generated request. When omitted or `false`, the automation can create one request per item.
* `lastProcessedItemId`: Optional item identifier to mark earlier content as already handled.

### Create an Explainer Automation Inline

For explainer videos, `/feeds/subscriptions` can create the template for you:

```bash
curl -X POST "https://api.autocontentapi.com/feeds/subscriptions" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "feedId": 42,
    "intervalMinutes": 720,
    "digestMode": true,
    "automation": {
      "type": "explainer",
      "instructions": "Turn each feed window into a short executive explainer with a clear takeaway.",
      "language": "English",
      "voiceId": 13,
      "titlePrompt": "Use a concise news headline",
      "thumbnailImagePrompt": "Clean editorial thumbnail with bold subject contrast"
    }
  }'
```

`voiceId` must be a numeric ID from `/content/GetVoices`.

List and remove subscriptions:

```bash
curl -X GET "https://api.autocontentapi.com/feeds/subscriptions" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

```bash
curl -X DELETE "https://api.autocontentapi.com/feeds/subscriptions/SUBSCRIPTION_ID" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

## Step 7: Reuse Feeds Elsewhere

Beyond podcasts, your saved feeds appear inside recurring X posts and other automations. Because all tools reference the same list, keeping feeds updated in the dashboard keeps every workflow in sync.

## Related Endpoints

* `POST /feeds` – Create a new feed.
* `GET /feeds` – List all feeds available to the account.
* `GET /feeds/{id}/items` – List cached feed items for `feedSelections`.
* `GET /feeds/subscriptions` – List feed subscriptions.
* `POST /feeds/subscriptions` – Create a feed subscription.
* `DELETE /feeds/subscriptions/{subscriptionId}` – Remove a feed subscription.
* `POST /feeds/delete` – Remove a feed by ID.

## What's Next?

* Turn a feed into audio using [Create a Podcast Episode from an X Feed](/quick-start/podcasts/create-feed-podcast).
* Schedule those episodes for release with the [Scheduler](/quick-start/podcasts/set-duration).
* Mix feeds with other sources when building a show via [Create a Podcast Episode](/quick-start/podcasts/create-podcast-episode).


# Modify an Existing Podcast

Refresh a published episode with new narration, instructions, or background audio. The `/content/ModifyPodcast` endpoint accepts an original `audioUrl`, blends in up to two new voices, and reprocesses the episode while keeping the structure you already shipped.

Call `/content/GetVoices` first and copy the numeric `id` values you want to use. The API rejects voice names such as `"Donna (Narrative)"` or `"DonnaNarrative"`.

## Step 1: Submit a Modify Request

```bash
curl -X POST "https://api.autocontentapi.com/content/ModifyPodcast" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "audioUrl": "https://storage.autocontentapi.com/audio/original-episode.mp3",
    "voice1": 13,
    "voice2": 45,
    "instructions": "Tighten the intro, add a stronger call-to-action, and update any dated references.",
    "backgroundMusicUrl": "https://cdn.example.com/audio/new-bed.mp3",
    "callbackData": "modifier-run-2024-05-01"
  }'
```

**Required fields**

* `audioUrl`: Public URL pointing to the episode you want to refresh.
* `voice1`, `voice2`: Numeric voice IDs from `/content/GetVoices`, the [Voices catalog](/voices), or your own clones. Both fields are required for `/content/ModifyPodcast`.

**Optional fields**

* `instructions`: Free-form guidance for the rewrite.
* `backgroundMusicUrl`: Backing track to mix under the hosts.
* `callbackData`: Arbitrary string returned in webhook notifications.

See [Track Requests & Status Codes](/quick-start/tools/track-requests) for the shared polling flow and reconciliation tips.

## Step 2: Track Progress

Use the returned `request_id` to poll `/content/Status/{id}` until `status` reaches `100`:

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/YOUR_REQUEST_ID" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

While processing you will see status codes `0` (pending) or `5` (running). Once complete, the payload includes `audio_url`, `response_text`, and `share_url` just like fresh creations.

## Tips

1. **Reuse existing instructions** – Start with the original prompt and only tweak what changed.
2. **Pair with clones** – Swap in [custom voices](/quick-start/tools/clone-voice) when the host has rebranded or the original narrator changed.
3. **Archive originals** – Store the previous audio in case you need to roll back or compare.


# Podcast Scenario Examples

Focused `curl` samples for tuning podcast generation. Each page mirrors the payloads assembled by the app while keeping instructions short and reusable. Swap `YOUR_API_TOKEN`, URLs, IDs, and text before running.

Prefer language SDKs? Jump to the [code samples](/code-samples/podcasts/podcast-examples) for side-by-side C#, Node.js, Java, PHP, and Python snippets.

## Available Recipes

* [🌐 Set Podcast Language](/quick-start/podcasts/set-language)
* [⏱️ Set Podcast Duration](/quick-start/podcasts/set-duration)
* [🎙️ Set Podcast Style](/quick-start/podcasts/set-style)
* [🎤 Use One Custom Voice](/quick-start/podcasts/single-custom-voice)
* [🔗 Create from a Website](/quick-start/podcasts/from-website)
* [▶️ Create from a YouTube Video](/quick-start/podcasts/from-youtube)
* [📝 Create from Raw Text](/quick-start/podcasts/from-text)
* [📄 Create from a PDF Upload](/quick-start/podcasts/from-pdf)
* [💡 Create from a Topic Prompt](/quick-start/podcasts/from-topic)
* [📜 Create from a Custom Script](/quick-start/podcasts/from-custom-script)
* [📰 Create from Saved Feeds](/quick-start/podcasts/from-feeds)
* [🔬 Create from Deep Research Results](/quick-start/podcasts/from-research)

Looking for the end-to-end workflow? Start with the [Create a Podcast Episode guide](/quick-start/podcasts/create-podcast-episode).


# Set Podcast Language

Target your audience with the right narration language. Provide the `language` field when you are not supplying custom voices.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "resources": [
      { "type": "website", "content": "https://example.com/ai-trends" }
    ],
    "text": "Highlight the three most actionable takeaways.",
    "language": "English"
  }'
```

**Key fields**

* `language`: Human-readable name from the [supported languages list](/languages).
* `resources`: Refer to any mix of source materials to ground the script.
* `text`: Give context or instructions to shape the episode.

## Try it in code

* [C#](/code-samples/podcasts/csharp/set-language)
* [Node.js](/code-samples/podcasts/nodejs/set-language)
* [Java](/code-samples/podcasts/java/set-language)
* [PHP](/code-samples/podcasts/php/set-language)
* [Python](/code-samples/podcasts/python/set-language)


# Set Podcast Duration

Control the target length of the generated episode by sending `duration`. The service supports `short`, `default`, and `long` presets.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "resources": [
      { "type": "youtube", "content": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }
    ],
    "text": "Summarize the key arguments in plain language.",
    "duration": "short"
  }'
```

**Key fields**

* `duration`: One of `short`, `default`, or `long`.
* `resources`: Combine any supported source types; YouTube is shown here.
* `text`: Use instructions to steer tone or focus.

## Try it in code

* [C#](/code-samples/podcasts/csharp/set-duration)
* [Node.js](/code-samples/podcasts/nodejs/set-duration)
* [Java](/code-samples/podcasts/java/set-duration)
* [PHP](/code-samples/podcasts/php/set-duration)
* [Python](/code-samples/podcasts/python/set-duration)


# Set Podcast Style

Pick a storytelling format such as `deep dive`, `brief`, `critique`, or `debate`. The style adjusts pacing and host banter.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "resources": [
      { "type": "text", "content": "The latest product launch generated strong community feedback..." }
    ],
    "text": "Turn this update into an engaging episode intro.",
    "style": "brief"
  }'
```

**Key fields**

* `style`: Choose from the supported presets (`deep dive`, `brief`, `critique`, `debate`).
* `resources`: Any mix is allowed; this example uses raw text.
* `text`: Guide the output by describing your goals or audience.

## Try it in code

* [C#](/code-samples/podcasts/csharp/set-style)
* [Node.js](/code-samples/podcasts/nodejs/set-style)
* [Java](/code-samples/podcasts/java/set-style)
* [PHP](/code-samples/podcasts/php/set-style)
* [Python](/code-samples/podcasts/python/set-style)


# Use One Custom Voice

Target a single narrator by calling the CustomVoices endpoint with only `voice1`. Voice fields must be numeric IDs from `/content/GetVoices`, not display names.

Fetch available voices first:

```bash
curl -X GET "https://api.autocontentapi.com/content/GetVoices" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

Example voice entry:

```json
{
  "id": 13,
  "name": "Donna (Narrative)",
  "gender": "f"
}
```

```bash
curl -X POST "https://api.autocontentapi.com/content/CreatePodcastCustomVoices" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "voice1": 13,
    "resources": [
      {
        "type": "text",
        "content": "Highlights from this week''s roadmap, customer wins, and upcoming launches."
      }
    ],
    "text": "Record this as a solo host update with a warm, confident tone."
  }'
```

**Key fields**

* `voice1`: Required when using CustomVoices; pass the numeric `id` value from `/content/GetVoices` or the [Voices catalog](/voices).
* `voice2`: Omit this field to keep a single-speaker format.
* `endpoint`: Use `/content/CreatePodcastCustomVoices` whenever you provide explicit voices.

## Try it in code

* [C#](/code-samples/podcasts/csharp/single-custom-voice)
* [Node.js](/code-samples/podcasts/nodejs/single-custom-voice)
* [Java](/code-samples/podcasts/java/single-custom-voice)
* [PHP](/code-samples/podcasts/php/single-custom-voice)
* [Python](/code-samples/podcasts/python/single-custom-voice)


# Create from a Website

Use a publicly accessible web page as the foundation for your episode. Provide the URL in a `website` resource object.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "resources": [
      { "type": "website", "content": "https://example.com/market-report" }
    ],
    "text": "Explain the long-term implications for small business owners."
  }'
```

**Tips**

* Include multiple website objects to blend different articles.
* Pair with `text` instructions to emphasize the insights you want surfaced.

## Try it in code

* [C#](/code-samples/podcasts/csharp/from-website)
* [Node.js](/code-samples/podcasts/nodejs/from-website)
* [Java](/code-samples/podcasts/java/from-website)
* [PHP](/code-samples/podcasts/php/from-website)
* [Python](/code-samples/podcasts/python/from-website)


# Create from a YouTube Video

Summarize or react to a YouTube video by sending its watch URL as a `youtube` resource.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "resources": [
      { "type": "youtube", "content": "https://www.youtube.com/watch?v=VIDEO_ID" }
    ],
    "text": "Share the top lessons and include relevant quotes."
  }'
```

**Tips**

* Use playlists or multiple video URLs for panel-style recaps.
* Provide timestamps in your `text` instructions to spotlight specific moments.

## Try it in code

* [C#](/code-samples/podcasts/csharp/from-youtube)
* [Node.js](/code-samples/podcasts/nodejs/from-youtube)
* [Java](/code-samples/podcasts/java/from-youtube)
* [PHP](/code-samples/podcasts/php/from-youtube)
* [Python](/code-samples/podcasts/python/from-youtube)


# Create from Raw Text

Paste prepared talking points or script snippets directly by sending a `text` resource.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "resources": [
      { "type": "text", "content": "Paragraph one... Paragraph two..." }
    ],
    "text": "Transform this memo into a conversational segment."
  }'
```

**Tips**

* Combine with other resource types for additional context.
* Keep long text chunks readable; the service trims excessive whitespace automatically.

## Try it in code

* [C#](/code-samples/podcasts/csharp/from-text)
* [Node.js](/code-samples/podcasts/nodejs/from-text)
* [Java](/code-samples/podcasts/java/from-text)
* [PHP](/code-samples/podcasts/php/from-text)
* [Python](/code-samples/podcasts/python/from-text)


# Create from a PDF Upload

Send a base64-encoded PDF to keep proprietary decks or reports private. Mark the resource `pdf` and include the encoded payload in `content`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "resources": [
      { "type": "pdf", "content": "BASE64_ENCODED_PDF" }
    ],
    "text": "Summarize the executive summary and cite supporting stats."
  }'
```

**Tips**

* Encode the PDF with `base64` (macOS/Linux: `base64 file.pdf`).
* For large files, share a pre-signed URL instead using a `website` resource.

## Try it in code

* [C#](/code-samples/podcasts/csharp/from-pdf)
* [Node.js](/code-samples/podcasts/nodejs/from-pdf)
* [Java](/code-samples/podcasts/java/from-pdf)
* [PHP](/code-samples/podcasts/php/from-pdf)
* [Python](/code-samples/podcasts/python/from-pdf)


# Create from a Topic Prompt

Let the AI research the subject for you by sending a `topic` without additional resources. Include `text` to define the angle.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "topic": "How remote teams can stay productive",
    "text": "Focus on tactics for hybrid startups."
  }'
```

**Tips**

* Add `duration`, `style`, or `language` fields to nail the format.
* Pair with custom instructions that list the exact talking points you expect.

## Try it in code

* [C#](/code-samples/podcasts/csharp/from-topic)
* [Node.js](/code-samples/podcasts/nodejs/from-topic)
* [Java](/code-samples/podcasts/java/from-topic)
* [PHP](/code-samples/podcasts/php/from-topic)
* [Python](/code-samples/podcasts/python/from-topic)


# Create from a Custom Script

Use the dedicated endpoint when you already have a full script marked with speaker labels (`SPEAKER_00`, `SPEAKER_01`, ...).

```bash
curl -X POST "https://api.autocontentapi.com/content/CreatePodcastCustomScript" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "script": "SPEAKER_00: Welcome back!\nSPEAKER_01: Today we dig into productivity hacks..."
  }'
```

**Tips**

* The service keeps your dialogue intact and focuses on delivery.
* Provide two or more voices if you want distinct hosts, or let defaults handle it.

## Try it in code

* [C#](/code-samples/podcasts/csharp/from-custom-script)
* [Node.js](/code-samples/podcasts/nodejs/from-custom-script)
* [Java](/code-samples/podcasts/java/from-custom-script)
* [PHP](/code-samples/podcasts/php/from-custom-script)
* [Python](/code-samples/podcasts/python/from-custom-script)


# Create from Saved Feeds

Leverage previously cached feed items by referencing a feed ID and selected item identifiers. Fetch selectable items with `GET /feeds/{feedId}/items`, then copy the returned item `identifier` values into `feedItemIds`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "feedSelections": [
      {
        "feedId": 42,
        "feedItemIds": ["1876982459012345678", "1876982459012345679"]
      }
    ],
    "text": "Summarize the most recent stories with actionable advice."
  }'
```

**Tips**

* Use the [Create a Podcast Episode from an X Feed](/quick-start/podcasts/create-feed-podcast) guide to create a feed and collect item identifiers.
* Combine feeds with other resource types for broader coverage.
* `feedSelections` replaces the older top-level `feeds` array.

## Try it in code

* [C#](/code-samples/podcasts/csharp/from-feeds)
* [Node.js](/code-samples/podcasts/nodejs/from-feeds)
* [Java](/code-samples/podcasts/java/from-feeds)
* [PHP](/code-samples/podcasts/php/from-feeds)
* [Python](/code-samples/podcasts/python/from-feeds)


# Create from Deep Research Results

Transform completed Deep Research runs into narrated episodes with the `researches` array.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "audio",
    "researches": ["research-id-123"],
    "text": "Present the findings and recommend next steps."
  }'
```

**Tips**

* Combine multiple research IDs for cross-study roundups.
* Pair with the [Create a Podcast Episode from Deep Research](/quick-start/deep-researches/create-research-podcast) walkthrough for status polling.

## Try it in code

* [C#](/code-samples/podcasts/csharp/from-research)
* [Node.js](/code-samples/podcasts/nodejs/from-research)
* [Java](/code-samples/podcasts/java/from-research)
* [PHP](/code-samples/podcasts/php/from-research)
* [Python](/code-samples/podcasts/python/from-research)


# Explainer Videos


# Create an Explainer Video

Produce your first AI-powered explainer video in just a few steps. This walkthrough uses the same `/content/Create` endpoint as podcasts, but switches the payload to `outputType: "video"` so the service renders motion visuals instead of audio-only narration. Video requests support three formats: `explainer`, `short`, and `cinematic`.

## Step 1: Create Content Request

Send a POST request to `/content/Create` with your preferred resources, set `outputType` to `video`, and optionally choose a `format`:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "resources": [
      {
        "type": "website",
        "content": "https://example.com/article-about-ai"
      },
      {
        "type": "youtube", 
        "content": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
      }
    ],
    "outputType": "video",
    "format": "explainer",
    "text": "Create an engaging explainer about current AI developments"
  }'
```

### Example Response

```json
{
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0
}
```

**Important:** Save the `request_id` — you'll use it to poll status and download the final video.

### Choose a format

Explainer video requests use `format` to control the output. If you still send the generic `duration` parameter, it is ignored:

| Format      | Best for                                                           | Credits |
| ----------- | ------------------------------------------------------------------ | ------- |
| `explainer` | Balanced default for most product, education, and marketing videos | 50      |
| `short`     | Tighter, punchier recaps and shorter social-friendly explainers    | 50      |
| `cinematic` | Premium, more polished storytelling treatment                      | 100     |

If you omit `format`, the API defaults to `explainer`. Use `style` separately when you want to change the visual aesthetic.

The old `brief` video format name has been replaced by `short`. Send `"format": "short"` for a tighter video; unsupported format names are rejected.

### Optional: Guide titles, descriptions, and visuals

Use these fields to steer how the service names and presents the video:

| Field                  | What it does                                                                                                       |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `title`                | Sets an explicit video title. When present, this overrides the auto-generated title.                               |
| `titlePrompt`          | Guides the model when auto-generating the title (e.g., ask for concise, listicle-style, or SEO-friendly phrasing). |
| `descriptionPrompt`    | Steers the generated video description (tone, call-to-action, hashtags, etc.).                                     |
| `thumbnailImagePrompt` | Directs the generated thumbnail artwork.                                                                           |
| `introImagePrompt`     | Directs the opening frame artwork.                                                                                 |

Add any combination of these to the POST body:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "resources": [
      {
        "type": "youtube",
        "content": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
      }
    ],
    "outputType": "video",
    "format": "short",
    "text": "Summarize this tutorial into a concise explainer for enterprise buyers",
    "title": "Modern Identity Security in 90 Seconds",
    "titlePrompt": "Keep it punchy and benefits-forward",
    "descriptionPrompt": "Include a one-sentence CTA to download the whitepaper",
    "thumbnailImagePrompt": "Flat illustration of a secure cloud, teal and navy palette, minimal text",
    "introImagePrompt": "Logo lockup on gradient with subtle motion trails"
  }'
```

### Optional: Use custom narration voices

Pass numeric voice IDs when you want to control narration. Get them from `/content/GetVoices` or the [Voices catalog](/voices). `voice2` is optional, but if you include it, you must also include `voice1`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "format": "short",
    "topic": "How passwordless authentication reduces help desk tickets",
    "voice1": 13,
    "voice2": 45,
    "text": "Use a conversational two-host narration and keep the video under two minutes."
  }'
```

### Optional: Apply your brand via `projects`

If you have a saved project with brand assets, include the `projects` array (pass one or more IDs) to place your logo on the generated video and thumbnail:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "format": "cinematic",
    "projects": ["YOUR_PROJECT_ID"],
    "topic": "Product launch overview with two customer wins",
    "text": "Create a polished launch explainer with a strong closing CTA."
  }'
```

See the [brand logo recipe](/quick-start/explainer-videos/brand-with-project-id) for more variations. Need a project first? Follow [Create a Project (Brand Assets)](/quick-start/tools/create-project) to save a logo via `imageUrl` or `imageData`.

## Step 2: Poll for Status

Use the `request_id` to check the processing status by calling `/content/Status/{id}`:

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/550e8400-e29b-41d4-a716-446655440000" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### While Processing

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 5,
  "updated_on": "2024-01-15T10:32:00Z",
  "error_code": 0,
  "requested_on": "2024-01-15T10:30:00Z"
}
```

**Status Codes:**

* `0` = Pending (queued for processing)
* `5` = Processing (generation in progress)
* `100` = Completed (video ready!)

## Step 3: Get Your Video

When `status` reaches `100`, the payload includes a link to your generated video:

Titles or prompts you set in Step 1 flow into `video_title`, and image prompts steer `image_url`/`thumbnail` assets returned here.

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "video_title": "AI Developments Discussion",
  "status": 100,
  "video_url": "https://storage.autocontentapi.com/video/550e8400-e29b-41d4-a716-446655440000.mp4",
  "image_url": "https://storage.autocontentapi.com/thumbnails/550e8400-e29b-41d4-a716-446655440000.jpg",
  "response_text": "Full narration that describes the generated visuals...",
  "requested_on": "2024-01-15T10:30:00Z",
  "updated_on": "2024-01-15T10:35:00Z",
  "request_type_id": 1,
  "error_code": 0,
  "error_on": null,
  "citations": [],
  "file_size": 51234567,
  "video_duration": 456,
  "share_url": "https://autocontentapi.com/share/video/550e8400-e29b-41d4-a716-446655440000/20240115"
}
```

**🎉 Success!** Your explainer video is ready at the `video_url`, and you can grab the thumbnail from `image_url`.

### List generated explainer videos

Use `/video/GetExplainerVideos` to list videos created through `/content/Create` with `outputType: "video"`:

```bash
curl -X GET "https://api.autocontentapi.com/video/GetExplainerVideos" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

This list is for explainer-video requests. Avatar video shorts created through `/video/CreateShorts`, `/video/CreateShortsFromContent`, `/video/CreateShortsFromScript`, or `/video/CreateShortsFromDeepResearch` are listed with `/video/GetShorts`.

## Resource Types

You can mix and match resource types just like you would for a podcast:

| Type      | Description         | Example                                      |
| --------- | ------------------- | -------------------------------------------- |
| `website` | Any web page URL    | `"https://techcrunch.com/article"`           |
| `youtube` | YouTube video URL   | `"https://www.youtube.com/watch?v=VIDEO_ID"` |
| `text`    | Direct text content | `"Your custom instructions or content"`      |
| `pdf`     | PDF document URL    | `"https://example.com/document.pdf"`         |

> Need a specific payload? Check the new [Explainer Video Scenario Examples](/quick-start/explainer-videos/explainer-video-examples) for copy-paste `curl` requests covering languages, formats, styles, and every supported resource type.

## Tips for Better Results

1. **Mix resource types** – Combine websites, videos, and text for richer storytelling.
2. **Provide clear instructions** – Use the `text` field to direct the pacing, tone, or call-to-action.
3. **Surface thumbnails** – Store the `image_url` for embedding preview artwork alongside the finished video.
4. **Check status regularly** – Processing typically takes 2-5 minutes for most requests; `cinematic` can take longer.
5. **Save the request\_id** – You'll need it to retrieve your video and any associated transcript.

## Error Handling

If something goes wrong, the status response will include error details:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0,
  "error_code": 400,
  "error_message": "Invalid resource URL provided",
  "error_on": "2024-01-15T10:31:00Z",
  "requested_on": "2024-01-15T10:30:00Z"
}
```

## What's Next?

* 🎨 Pick reusable formats and styles in [Explainer Video Scenario Examples](/quick-start/explainer-videos/explainer-video-examples)
* 🧪 Explore language-specific snippets in the [video code samples](/code-samples/explainer-videos/video-explainer-samples)
* 🎙️ Add branded voices with [Clone a Voice](/quick-start/tools/clone-voice)
* 📝 Need captions? Run the final audio track through [Transcribe Audio](/quick-start/tools/transcribe-audio)
* 🔮 Check out [Advanced Integrations](/integrations) for automation ideas
* ❓ Have questions? Visit our [FAQ](/faq)


# Explainer Video Scenario Examples

Focused `curl` samples for tuning explainer video generation. Each page mirrors the payloads assembled by the app while keeping instructions short and reusable. Video requests use `format` (`explainer`, `short`, or `cinematic`); if `duration` is sent, it is ignored. Swap `YOUR_API_TOKEN`, URLs, IDs, and text before running.

Prefer language SDKs? Jump to the [code samples](/code-samples/explainer-videos/video-explainer-samples) for side-by-side C#, Node.js, Java, PHP, and Python snippets.

## Available Recipes

* [🌐 Set Explainer Video Language](/quick-start/explainer-videos/set-language)
* [🎬 Choose Explainer Video Format](/quick-start/explainer-videos/set-duration)
* [🎙️ Set Explainer Video Style](/quick-start/explainer-videos/set-style)
* [🏷️ Guide Titles, Descriptions, and Artwork](/quick-start/explainer-videos/set-titles-and-images)
* [🏢 Apply Brand Logo with `projectId`](/quick-start/explainer-videos/brand-with-project-id)
* [🔗 Create from a Website](/quick-start/explainer-videos/from-website)
* [▶️ Create from a YouTube Video](/quick-start/explainer-videos/from-youtube)
* [📝 Create from Raw Text](/quick-start/explainer-videos/from-text)
* [📄 Create from a PDF Upload](/quick-start/explainer-videos/from-pdf)
* [💡 Create from a Topic Prompt](/quick-start/explainer-videos/from-topic)
* [📜 Create from a Custom Script](/quick-start/explainer-videos/from-custom-script)
* [📰 Create from Saved Feeds](/quick-start/explainer-videos/from-feeds)
* [🔬 Create from Deep Research Results](/quick-start/explainer-videos/from-research)

Looking for the end-to-end workflow? Start with the [Create an Explainer Video guide](/quick-start/explainer-videos/create-explainer-video).


# Set Explainer Video Language

Target your audience with the right narration language. Provide the `language` field when you are not supplying custom voices.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "resources": [
      { "type": "website", "content": "https://example.com/ai-trends" }
    ],
    "text": "Highlight the three most actionable takeaways.",
    "language": "English"
  }'
```

**Key fields**

* `language`: Human-readable name from the [supported languages list](/languages).
* `resources`: Refer to any mix of source materials to ground the script.
* `text`: Give context or instructions to shape the video.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/set-language)
* [Node.js](/code-samples/explainer-videos/nodejs/set-language)
* [Java](/code-samples/explainer-videos/java/set-language)
* [PHP](/code-samples/explainer-videos/php/set-language)
* [Python](/code-samples/explainer-videos/python/set-language)


# Choose Explainer Video Format

Explainer video requests use `format` to choose how the video is produced. If the generic `duration` parameter is sent, it is ignored.

| Format      | Best for                                               | Credits |
| ----------- | ------------------------------------------------------ | ------- |
| `explainer` | Balanced default for most explainers                   | 50      |
| `short`     | Tighter, punchier summaries and social-friendly recaps | 50      |
| `cinematic` | Premium, more polished storytelling treatment          | 100     |

If you omit `format`, the API defaults to `explainer`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "resources": [
      { "type": "youtube", "content": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }
    ],
    "text": "Summarize the key arguments in plain language.",
    "format": "short"
  }'
```

**Key fields**

* `format`: One of `explainer`, `short`, or `cinematic`.
* `resources`: Combine any supported source types; YouTube is shown here.
* `style`: Optional visual treatment layered on top of the chosen format.
* `text`: Use instructions to steer tone or focus.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/set-duration)
* [Node.js](/code-samples/explainer-videos/nodejs/set-duration)
* [Java](/code-samples/explainer-videos/java/set-duration)
* [PHP](/code-samples/explainer-videos/php/set-duration)
* [Python](/code-samples/explainer-videos/python/set-duration)


# Set Explainer Video Style

Pick a visual storytelling preset such as `classic`, `whiteboard`, `watercolor`, `retro`, `heritage`, `paper-craft`, or `anime`. Styles influence camera moves, transitions, and color palettes. Use `format` separately when you want to switch between `explainer`, `short`, and `cinematic`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "resources": [
      { "type": "text", "content": "The latest product launch generated strong community feedback..." }
    ],
    "format": "explainer",
    "text": "Turn this update into an engaging explainer intro.",
    "style": "whiteboard"
  }'
```

**Key fields**

* `style`: Choose from the supported presets (`classic`, `whiteboard`, `watercolor`, `retro`, `heritage`, `paper-craft`, `anime`).
* `format`: Optional output format (`explainer`, `short`, or `cinematic`). `explainer` is the default.
* `resources`: Any mix is allowed; this example uses raw text.
* `text`: Guide the output by describing your goals or audience.

**Tips**

* Pick `anime` or `paper-craft` for stylized campaigns; stick with `classic` when you need broad appeal.
* Use `short` when you want a tighter delivery, and `cinematic` when you want a premium treatment. Keep `style` focused on art direction.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/set-style)
* [Node.js](/code-samples/explainer-videos/nodejs/set-style)
* [Java](/code-samples/explainer-videos/java/set-style)
* [PHP](/code-samples/explainer-videos/php/set-style)
* [Python](/code-samples/explainer-videos/python/set-style)


# Guide Titles, Descriptions, and Artwork

Control how explainer videos are named and presented by supplying metadata prompts. These fields work only with `outputType: "video"` on `/content/Create`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "resources": [
      { "type": "text", "content": "Explain zero trust security in plain language." }
    ],
    "text": "Aim this at enterprise IT buyers who want a quick overview.",
    "title": "Zero Trust Security in 90 Seconds",
    "titlePrompt": "Keep it concise and benefits-forward",
    "descriptionPrompt": "Close with a CTA to download the whitepaper and mention SOC2 compliance",
    "thumbnailImagePrompt": "Isometric cloud shield in teal and navy, minimal text overlay, clean gradients",
    "introImagePrompt": "Logo over deep blue gradient with subtle light trails"
  }'
```

**Key fields**

* `title`: Explicit title that overrides the automatically generated one.
* `titlePrompt`: Guidance for auto-generated titles (useful when you do not set `title` or want a style hint).
* `descriptionPrompt`: Instructions for the generated description (tone, CTA, hashtags).
* `thumbnailImagePrompt`: Visual direction for the thumbnail the API returns as `image_url`.
* `introImagePrompt`: Visual direction for the opening frame.

Poll `/content/Status/{id}` to see your choices reflected in `video_title` and the returned imagery URLs.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/set-titles-and-images)
* [Node.js](/code-samples/explainer-videos/nodejs/set-titles-and-images)
* [Java](/code-samples/explainer-videos/java/set-titles-and-images)
* [PHP](/code-samples/explainer-videos/php/set-titles-and-images)
* [Python](/code-samples/explainer-videos/python/set-titles-and-images)


# Apply Brand Logo with projectId

Use the `projects` array (supply one or more project IDs) to attach your saved brand assets (e.g., company logo) to explainer video outputs. Add it to the `/content/Create` payload alongside `outputType: "video"`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "projects": ["YOUR_PROJECT_ID"],
    "resources": [
      { "type": "text", "content": "Explain our new platform launch and highlight customer success data." }
    ],
    "text": "Keep this to 90 seconds with a product intro, key proof points, and a closing CTA.",
    "titlePrompt": "Short, benefit-led launch teaser"
  }'
```

**What `projects` does**

* Pulls your stored brand package to place the company logo into the video frames and thumbnail.
* Keeps other content controls intact (language, style, format, title/description prompts).

Poll `/content/Status/{id}` as usual to retrieve the finished video and logo-bearing thumbnail.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/brand-with-project-id)
* [Node.js](/code-samples/explainer-videos/nodejs/brand-with-project-id)
* [Java](/code-samples/explainer-videos/java/brand-with-project-id)
* [PHP](/code-samples/explainer-videos/php/brand-with-project-id)
* [Python](/code-samples/explainer-videos/python/brand-with-project-id)


# Create from a Website

Use a publicly accessible web page as the foundation for your video. Provide the URL in a `website` resource object.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "resources": [
      { "type": "website", "content": "https://example.com/market-report" }
    ],
    "text": "Explain the long-term implications for small business owners."
  }'
```

**Tips**

* Include multiple website objects to blend different articles.
* Pair with `text` instructions to emphasize the insights you want surfaced.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/from-website)
* [Node.js](/code-samples/explainer-videos/nodejs/from-website)
* [Java](/code-samples/explainer-videos/java/from-website)
* [PHP](/code-samples/explainer-videos/php/from-website)
* [Python](/code-samples/explainer-videos/python/from-website)


# Create from a YouTube Video

Summarize or react to a YouTube video by sending its watch URL as a `youtube` resource.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "resources": [
      { "type": "youtube", "content": "https://www.youtube.com/watch?v=VIDEO_ID" }
    ],
    "text": "Share the top lessons and include relevant quotes."
  }'
```

**Tips**

* Use playlists or multiple video URLs for panel-style recaps.
* Provide timestamps in your `text` instructions to spotlight specific moments.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/from-youtube)
* [Node.js](/code-samples/explainer-videos/nodejs/from-youtube)
* [Java](/code-samples/explainer-videos/java/from-youtube)
* [PHP](/code-samples/explainer-videos/php/from-youtube)
* [Python](/code-samples/explainer-videos/python/from-youtube)


# Create from Raw Text

Paste prepared talking points or script snippets directly by sending a `text` resource.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "resources": [
      { "type": "text", "content": "Paragraph one... Paragraph two..." }
    ],
    "text": "Transform this memo into a conversational segment."
  }'
```

**Tips**

* Combine with other resource types for additional context.
* Keep long text chunks readable; the service trims excessive whitespace automatically.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/from-text)
* [Node.js](/code-samples/explainer-videos/nodejs/from-text)
* [Java](/code-samples/explainer-videos/java/from-text)
* [PHP](/code-samples/explainer-videos/php/from-text)
* [Python](/code-samples/explainer-videos/python/from-text)


# Create from a PDF Upload

Send a base64-encoded PDF to keep proprietary decks or reports private. Mark the resource `pdf` and include the encoded payload in `content`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "resources": [
      { "type": "pdf", "content": "BASE64_ENCODED_PDF" }
    ],
    "text": "Summarize the executive summary and cite supporting stats."
  }'
```

**Tips**

* Encode the PDF with `base64` (macOS/Linux: `base64 file.pdf`).
* For large files, share a pre-signed URL instead using a `website` resource.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/from-pdf)
* [Node.js](/code-samples/explainer-videos/nodejs/from-pdf)
* [Java](/code-samples/explainer-videos/java/from-pdf)
* [PHP](/code-samples/explainer-videos/php/from-pdf)
* [Python](/code-samples/explainer-videos/python/from-pdf)


# Create from a Topic Prompt

Let the AI research the subject for you by sending a `topic` without additional resources. Include `text` to define the angle.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "topic": "How remote teams can stay productive",
    "text": "Focus on tactics for hybrid startups."
  }'
```

**Tips**

* Add `format`, `style`, or `language` fields to tune the output.
* Pair with custom instructions that list the exact talking points you expect.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/from-topic)
* [Node.js](/code-samples/explainer-videos/nodejs/from-topic)
* [Java](/code-samples/explainer-videos/java/from-topic)
* [PHP](/code-samples/explainer-videos/php/from-topic)
* [Python](/code-samples/explainer-videos/python/from-topic)


# Create from a Custom Script

Provide a complete script marked with speaker labels (`SPEAKER_00`, `SPEAKER_01`, ...) to control every line in your video. Send it through the standard creation endpoint via the `text` field.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "format": "short",
    "voice1": 13,
    "voice2": 45,
    "text": "SPEAKER_00: Welcome back!\nSPEAKER_01: Today we dig into productivity hacks..."
  }'
```

**Tips**

* Keep each line prefixed with `SPEAKER_00:` or `SPEAKER_01:` so the service can match voices.
* Add optional `voice1` / `voice2` fields when you need precise host selection. These must be numeric IDs from `/content/GetVoices`; do not send voice names.
* Scripts over 5,000 characters may be rejected—split longer pieces into multiple videos.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/from-custom-script)
* [Node.js](/code-samples/explainer-videos/nodejs/from-custom-script)
* [Java](/code-samples/explainer-videos/java/from-custom-script)
* [PHP](/code-samples/explainer-videos/php/from-custom-script)
* [Python](/code-samples/explainer-videos/python/from-custom-script)


# Create from Saved Feeds

Leverage previously cached feed items by referencing a feed ID and selected item identifiers. Fetch selectable items with `GET /feeds/{feedId}/items`, then copy the returned item `identifier` values into `feedItemIds`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "format": "short",
    "feedSelections": [
      {
        "feedId": 42,
        "feedItemIds": ["1876982459012345678", "1876982459012345679"]
      }
    ],
    "text": "Summarize the most recent stories with actionable advice."
  }'
```

**Tips**

* Use the [Create a Podcast Episode from an X Feed](/quick-start/podcasts/create-feed-podcast) guide to create a feed and collect item identifiers.
* Combine feeds with other resource types for broader coverage.
* `feedSelections` replaces the older top-level `feeds` array.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/from-feeds)
* [Node.js](/code-samples/explainer-videos/nodejs/from-feeds)
* [Java](/code-samples/explainer-videos/java/from-feeds)
* [PHP](/code-samples/explainer-videos/php/from-feeds)
* [Python](/code-samples/explainer-videos/python/from-feeds)


# Create from Deep Research Results

Transform completed Deep Research runs into narrated videos with the `researches` array.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "video",
    "researches": ["research-id-123"],
    "text": "Present the findings and recommend next steps."
  }'
```

**Tips**

* Combine multiple research IDs for cross-study roundups.
* Run [Create a Podcast Episode from Deep Research](/quick-start/deep-researches/create-research-podcast) first to capture research IDs, then reuse them here.

## Try it in code

* [C#](/code-samples/explainer-videos/csharp/from-research)
* [Node.js](/code-samples/explainer-videos/nodejs/from-research)
* [Java](/code-samples/explainer-videos/java/from-research)
* [PHP](/code-samples/explainer-videos/php/from-research)
* [Python](/code-samples/explainer-videos/python/from-research)


# Infographics


# Infographic Scenario Examples

Focused `curl` samples for generating visual one-pagers. Each recipe uses `/content/Create` with `outputType: "infographic"` and highlights how to control orientation and detail while keeping payloads small.

## Available Recipes

* [📝 Create an Infographic from Text](/quick-start/infographics/from-text)
* [🔗 Create an Infographic from a Website](/quick-start/infographics/from-website)
* [📐 Control Orientation and Detail](/quick-start/infographics/set-orientation-and-detail)
* [💡 Create an Infographic from a Topic Prompt](/quick-start/infographics/from-topic)
* [🏢 Apply Brand Logo with `projectId`](/quick-start/infographics/brand-with-project-id)

Ready to ship? Start with the text recipe, then mix in additional resources or tweak layout knobs as needed.


# Create an Infographic from Text

Combine a text resource with clear layout guidance to produce a clean visual summary.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "infographic",
    "resources": [
      { "type": "text", "content": "Three key takeaways about electric vehicle adoption and charging growth." }
    ],
    "text": "Create a single-page infographic with bold section headers, a concise stat block, and one chart-ready callout.",
    "infographicOrientation": "portrait",
    "infographicDetail": "detailed"
  }'
```

**Tips**

* Keep the `text` instructions punchy so the infographic layout stays focused.
* Switch `infographicOrientation` between `landscape`, `portrait`, and `square` to match your destination.
* Use `infographicDetail` (`concise`, `standard`, `detailed`) to balance brevity versus depth.


# Create an Infographic from a Website

Pull highlights from a URL and turn them into a branded infographic.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "infographic",
    "resources": [
      { "type": "website", "content": "https://example.com/2024-market-report" }
    ],
    "text": "Summarize the report with three numeric callouts, a comparison chart, and a short takeaway section.",
    "infographicOrientation": "landscape",
    "infographicDetail": "standard"
  }'
```

**Tips**

* Pair a `website` resource with a short `text` brief so the generator knows which angles to emphasize.
* Portrait works best for mobile or email; landscape fits dashboards and slide inserts.


# Control Orientation and Detail

Tune the layout without changing your source material by setting the infographic orientation and detail level explicitly.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "infographic",
    "topic": "Key milestones in quantum computing",
    "infographicOrientation": "square",
    "infographicDetail": "concise",
    "callbackData": "infographic-layout-test"
  }'
```

**Tips**

* `infographicOrientation` supports `landscape`, `portrait`, and `square` — pick based on where you will embed the graphic.
* `infographicDetail` keeps density in check: start with `standard`, then move to `concise` for social or `detailed` for reports.
* `callbackData` can store your own tracking string for webhook flows.


# Create an Infographic from a Topic Prompt

Skip sourcing links and let the service research a topic for you. Provide a `topic` and optional `text` to define the angle, then set layout knobs if needed.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "infographic",
    "topic": "How electric vehicle charging networks are expanding in cities",
    "text": "Keep it friendly for city planners and show two key stats plus one map-style callout.",
    "infographicOrientation": "portrait",
    "infographicDetail": "standard"
  }'
```

**Tips**

* Add `infographicOrientation` (`portrait`, `landscape`, `square`) to match where you will embed the asset.
* Use `infographicDetail` (`concise`, `standard`, `detailed`) to adjust depth.
* Pair `text` with your intended audience or CTA to steer tone.

## Try it in code

* [C#](/code-samples/infographics/csharp/from-topic)
* [Node.js](/code-samples/infographics/nodejs/from-topic)
* [Java](/code-samples/infographics/java/from-topic)
* [PHP](/code-samples/infographics/php/from-topic)
* [Python](/code-samples/infographics/python/from-topic)


# Apply Brand Logo with projectId

Use the `projects` array (one or more project IDs) to apply your stored brand assets (like company logos) to infographic outputs. Add it to `/content/Create` with `outputType: "infographic"`. Need a project first? Follow [Create a Project (Brand Assets)](/quick-start/tools/create-project) to save a logo via `imageUrl` or `imageData`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "infographic",
    "projects": ["YOUR_PROJECT_ID"],
    "topic": "Key AI safety principles for enterprise teams",
    "text": "Keep it board-friendly with three headline callouts, a stat block, and a footer CTA.",
    "infographicOrientation": "portrait",
    "infographicDetail": "standard"
  }'
```

**What `projects` does**

* Pulls your saved brand package to place logos on the generated infographic.
* Works with any input type (topic, website, text) and all layout options.

Poll `/content/Status/{id}` to fetch the branded asset URL.

## Try it in code

* [C#](/code-samples/infographics/csharp/brand-with-project-id)
* [Node.js](/code-samples/infographics/nodejs/brand-with-project-id)
* [Java](/code-samples/infographics/java/brand-with-project-id)
* [PHP](/code-samples/infographics/php/brand-with-project-id)
* [Python](/code-samples/infographics/python/brand-with-project-id)


# Documents


# Create a Briefing Document

Generate NotebookLM-style briefing documents by calling `/content/Create` with `outputType: "briefing_doc"`. The API supports three result formats:

* `pdf` — uploads a generated PDF and returns a URL
* `html` — returns structured HTML content
* `text` — returns plain text content

If you omit `format`, the API defaults to `pdf`.

Need a reusable file ID for a private PDF first? Follow [Upload Private Files](/quick-start/tools/upload-files).

## Step 1: Create the Document Request

Send a POST request to `/content/Create` with your source material and set `outputType` to `briefing_doc`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "briefing_doc",
    "format": "pdf",
    "resources": [
      {
        "type": "website",
        "content": "https://example.com/enterprise-ai-market-update"
      }
    ],
    "text": "Create an executive briefing for B2B SaaS leaders. Include market shifts, key risks, and recommended actions.",
    "language": "English"
  }'
```

### Example Response

```json
{
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0
}
```

Save the `request_id`. You will use it both for `/content/Status/{id}` and for the `/documents` endpoints.

## Step 2: Poll for Status

Use the returned `request_id` to track generation progress:

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/550e8400-e29b-41d4-a716-446655440000" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### While Processing

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 80,
  "updated_on": "2026-03-11T19:10:00Z",
  "error_code": 0,
  "requested_on": "2026-03-11T19:08:00Z"
}
```

### Status Values

* `0` = Pending or queued
* `5` = Early processing stages
* `80` = Document generation in progress
* `100` = Completed

## Step 3: Read the Result from `/content/Status/{id}`

The final payload depends on the selected `format`.

### Completed PDF Result

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "audio_title": "Briefing Document: Enterprise AI Market Update",
  "status": 100,
  "audio_url": "https://autocontentapi.blob.core.windows.net/audios/briefing-doc-550e8400.pdf",
  "response_text": "",
  "requested_on": "2026-03-11T19:08:00Z",
  "updated_on": "2026-03-11T19:12:00Z",
  "request_type_id": 1,
  "error_code": 0,
  "error_on": null,
  "citations": [],
  "file_size": 0,
  "audio_duration": 0,
  "share_url": "https://autocontentapi.blob.core.windows.net/audios/briefing-doc-550e8400.pdf",
  "briefing_doc_url": "https://autocontentapi.blob.core.windows.net/audios/briefing-doc-550e8400.pdf",
  "document_type": "briefing_doc",
  "document_format": "pdf",
  "document_content": "",
  "document_url": "https://autocontentapi.blob.core.windows.net/audios/briefing-doc-550e8400.pdf",
  "title": "Briefing Document: Enterprise AI Market Update"
}
```

### Completed HTML or Text Result

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "audio_title": "Briefing Document: Enterprise AI Market Update",
  "status": 100,
  "audio_url": "",
  "response_text": "## Executive Summary\n\nThe enterprise AI market is consolidating around...",
  "requested_on": "2026-03-11T19:08:00Z",
  "updated_on": "2026-03-11T19:12:00Z",
  "request_type_id": 1,
  "error_code": 0,
  "error_on": null,
  "citations": [],
  "file_size": 0,
  "audio_duration": 0,
  "share_url": "",
  "briefing_doc_url": "",
  "document_type": "briefing_doc",
  "document_format": "text",
  "document_content": "## Executive Summary\n\nThe enterprise AI market is consolidating around...",
  "document_url": "",
  "title": "Briefing Document: Enterprise AI Market Update"
}
```

Use `document_format` to branch your client logic:

* `pdf`: read `briefing_doc_url` or `document_url`
* `html`: read `document_content`
* `text`: read `document_content` or `response_text`

## Step 4: Use the Documents API

The content status endpoint is enough for polling, but completed documents are also available through `/documents`.

### List Documents

```bash
curl -X GET "https://api.autocontentapi.com/documents/get?page=1&pageSize=10" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

Example response:

```json
{
  "items": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "type": "briefing_doc",
      "format": "pdf",
      "title": "Briefing Document: Enterprise AI Market Update",
      "createdOn": "2026-03-11T19:12:00Z",
      "status": 100
    }
  ],
  "totalCount": 1,
  "page": 1,
  "pageSize": 10,
  "totalPages": 1
}
```

### Fetch One Document

```bash
curl -X GET "https://api.autocontentapi.com/documents/550e8400-e29b-41d4-a716-446655440000" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

Example PDF response:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "briefing_doc",
  "format": "pdf",
  "title": "Briefing Document: Enterprise AI Market Update",
  "status": 100,
  "createdOn": "2026-03-11T19:12:00Z",
  "content": "",
  "url": "https://autocontentapi.blob.core.windows.net/audios/briefing-doc-550e8400.pdf"
}
```

Example HTML response:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "briefing_doc",
  "format": "html",
  "title": "Briefing Document: Enterprise AI Market Update",
  "status": 100,
  "createdOn": "2026-03-11T19:12:00Z",
  "content": "<h2>Executive Summary</h2><p>The enterprise AI market is consolidating...</p>",
  "url": ""
}
```

### Download the Stored Asset

```bash
curl -L "https://api.autocontentapi.com/documents/550e8400-e29b-41d4-a716-446655440000/download" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -o briefing-document.pdf
```

The download endpoint returns the correct file type automatically:

* PDF download for `format: "pdf"`
* `.html` download for `format: "html"`
* `.txt` download for `format: "text"`

## Supported Source Types

You can generate briefing documents from the same main source types used by other content endpoints:

| Type      | Description                                                                 | Example                                      |
| --------- | --------------------------------------------------------------------------- | -------------------------------------------- |
| `website` | Public web page URL                                                         | `"https://example.com/report"`               |
| `youtube` | YouTube video URL                                                           | `"https://www.youtube.com/watch?v=VIDEO_ID"` |
| `text`    | Direct text instructions or source material                                 | `"Internal memo content..."`                 |
| `pdf`     | Base64-encoded PDF payload                                                  | `"BASE64_ENCODED_PDF"`                       |
| `file`    | File ID returned by [Upload Private Files](/quick-start/tools/upload-files) | `"YOUR_FILE_ID"`                             |

## Format Options

| Format | Behavior                                        | Best for                                        |
| ------ | ----------------------------------------------- | ----------------------------------------------- |
| `pdf`  | Generates a downloadable PDF and stores its URL | Client deliverables, handoffs, downloads        |
| `html` | Returns structured HTML in the API response     | CMS ingestion, rendering in apps                |
| `text` | Returns plain text content                      | Summaries, internal automation, search indexing |

## Tips for Better Results

1. Use `text` to specify audience, structure, and level of detail.
2. Pick `pdf` when humans will download the deliverable, and `html` or `text` when another system will consume it.
3. Poll `/content/Status/{id}` until `status` reaches `100` before calling `/documents/{id}`.
4. Use `/documents/get` to build document history views in your app.
5. If you need private PDFs, upload them first via [Upload Private Files](/quick-start/tools/upload-files) and reference the returned file ID with `type: "file"`.

## Error Handling

If generation fails, `/content/Status/{id}` returns the error metadata just like other content types:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0,
  "error_code": 500,
  "error_message": "Unable to process this briefing document request right now. Please try again.",
  "error_on": "2026-03-11T19:09:30Z",
  "requested_on": "2026-03-11T19:08:00Z"
}
```

## What's Next?

* 📚 Browse the [Document Scenario Examples](/quick-start/documents/document-examples)
* 💻 Use the [Document Code Samples](/code-samples/documents/document-examples)
* 🔬 Combine research outputs with [Deep Research](/quick-start/deep-researches/start-deep-research)
* 📁 Upload a private PDF first with the Files API, then reference it as a `file` resource


# Document Scenario Examples

Focused `curl` recipes for generating briefing documents with `/content/Create` and `outputType: "briefing_doc"`. These examples cover the main source types, output formats, language overrides, and the dedicated retrieval endpoints.

## Available Recipes

* [📝 Create a Briefing Document from Text](/quick-start/documents/from-text)
* [🔗 Create a Briefing Document from a Website](/quick-start/documents/from-website)
* [💡 Create a Briefing Document from a Topic Prompt](/quick-start/documents/from-topic)
* [📄 Create a Briefing Document from a PDF Upload](/quick-start/documents/from-pdf)
* [🌐 Set Document Format and Language](/quick-start/documents/set-format-and-language)
* [📥 List, Fetch, and Download Documents](/quick-start/documents/retrieve-and-download)

Start with the text recipe, then move to `html` or `pdf` depending on how you plan to consume the result.

Need a `fileId` for private PDFs first? Use [Upload Private Files](/quick-start/tools/upload-files).


# Create a Briefing Document from Text

Generate a structured briefing directly from written source material.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "briefing_doc",
    "format": "text",
    "resources": [
      {
        "type": "text",
        "content": "Q1 board memo: revenue growth slowed to 11%, enterprise expansion remains strongest, sales cycles increased by 18 days, and churn improved by 0.7 points."
      }
    ],
    "text": "Create an executive briefing with summary, risks, and action items.",
    "language": "English"
  }'
```

**Tips**

* Use `format: "text"` when you want to feed the result into search, automation, or LLM follow-up steps.
* Keep the prompt in `text` focused on structure: summary, bullet points, recommendations, and intended audience.
* Poll `/content/Status/{id}` and read `document_content` once the request reaches `100`.

## Try it in code

* [C#](/code-samples/documents/csharp/from-text)
* [Node.js](/code-samples/documents/nodejs/from-text)
* [Java](/code-samples/documents/java/from-text)
* [PHP](/code-samples/documents/php/from-text)
* [Python](/code-samples/documents/python/from-text)


# Create a Briefing Document from a Website

Turn a public URL into a client-ready briefing document.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "briefing_doc",
    "format": "html",
    "resources": [
      {
        "type": "website",
        "content": "https://example.com/2026-cloud-security-report"
      }
    ],
    "text": "Summarize the report for CISOs. Use sections for market context, top threats, and recommended priorities.",
    "language": "English"
  }'
```

**Tips**

* Use `format: "html"` when you want to render the briefing inside your own product or CMS.
* Add a short instruction in `text` so the generator knows the target audience and desired structure.
* Once complete, use `/documents/{id}` to fetch the normalized HTML payload.

## Try it in code

* [C#](/code-samples/documents/csharp/from-website)
* [Node.js](/code-samples/documents/nodejs/from-website)
* [Java](/code-samples/documents/java/from-website)
* [PHP](/code-samples/documents/php/from-website)
* [Python](/code-samples/documents/python/from-website)


# Create a Briefing Document from a Topic Prompt

Let the API research a topic and assemble the briefing for you.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "briefing_doc",
    "format": "pdf",
    "topic": "How European AI regulation is affecting enterprise software vendors",
    "text": "Write for GTM and product leaders. Include key policy shifts, business implications, and next-step recommendations.",
    "language": "English"
  }'
```

**Tips**

* `topic` is useful when you want the service to gather context instead of supplying source URLs yourself.
* Use `format: "pdf"` for external deliverables you plan to share with clients or executives.
* Add an audience in `text` to control tone and level of detail.

## Try it in code

* [C#](/code-samples/documents/csharp/from-topic)
* [Node.js](/code-samples/documents/nodejs/from-topic)
* [Java](/code-samples/documents/java/from-topic)
* [PHP](/code-samples/documents/php/from-topic)
* [Python](/code-samples/documents/python/from-topic)


# Create a Briefing Document from a PDF Upload

Use a PDF as the source when you want to summarize a private report, whitepaper, or internal deck.

You can either:

* send a base64 payload with `type: "pdf"`, or
* upload the file first by following [Upload Private Files](/quick-start/tools/upload-files) and send the returned file ID with `type: "file"`

### Option A: Base64 PDF Payload

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "briefing_doc",
    "format": "pdf",
    "resources": [
      {
        "type": "pdf",
        "content": "BASE64_ENCODED_PDF"
      }
    ],
    "text": "Extract the executive summary, highlight three supporting data points, and end with recommended actions."
  }'
```

### Option B: Uploaded File ID

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "briefing_doc",
    "format": "html",
    "resources": [
      {
        "type": "file",
        "content": "YOUR_FILE_ID"
      }
    ],
    "text": "Turn this uploaded report into an HTML briefing with headings, bullets, and a recommendations section."
  }'
```

**Tips**

* Use `type: "file"` when the PDF is large or private.
* Use `format: "html"` if the output will be embedded in your application.
* Use `format: "pdf"` if you want the result as a downloadable asset URL.

## Try it in code

* [C#](/code-samples/documents/csharp/from-pdf)
* [Node.js](/code-samples/documents/nodejs/from-pdf)
* [Java](/code-samples/documents/java/from-pdf)
* [PHP](/code-samples/documents/php/from-pdf)
* [Python](/code-samples/documents/python/from-pdf)


# Set Document Format and Language

Use `format` to control the returned artifact and `language` to control the writing language.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "briefing_doc",
    "topic": "State of AI procurement in healthcare",
    "text": "Keep it suitable for hospital executives and procurement teams.",
    "format": "html",
    "language": "español"
  }'
```

## Format Behavior

* `pdf`: returns `briefing_doc_url` and `document_url` when complete
* `html`: returns HTML in `document_content`
* `text`: returns plain text in `document_content`

## Tips

* Choose `pdf` for handoffs and direct downloads.
* Choose `html` when you plan to render the result in a browser or CMS.
* Choose `text` when you want the cleanest format for downstream automation.
* `language` applies to the generated briefing content, not just the title.

## Try it in code

* [C#](/code-samples/documents/csharp/set-format-and-language)
* [Node.js](/code-samples/documents/nodejs/set-format-and-language)
* [Java](/code-samples/documents/java/set-format-and-language)
* [PHP](/code-samples/documents/php/set-format-and-language)
* [Python](/code-samples/documents/python/set-format-and-language)


# List, Fetch, and Download Documents

Once a briefing document has been generated successfully, you can manage it through the dedicated `/documents` endpoints.

## 1. List Documents

```bash
curl -X GET "https://api.autocontentapi.com/documents/get?page=1&pageSize=20" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

Example response:

```json
{
  "items": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "type": "briefing_doc",
      "format": "pdf",
      "title": "Briefing Document: AI Procurement in Healthcare",
      "createdOn": "2026-03-11T19:12:00Z",
      "status": 100
    }
  ],
  "totalCount": 1,
  "page": 1,
  "pageSize": 20,
  "totalPages": 1
}
```

## 2. Fetch One Document

```bash
curl -X GET "https://api.autocontentapi.com/documents/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

For `format: "pdf"`, the response includes `url`. For `format: "text"` or `format: "html"`, the response includes `content`.

## 3. Download the Stored Result

```bash
curl -L "https://api.autocontentapi.com/documents/550e8400-e29b-41d4-a716-446655440000/download" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -o briefing-document.pdf
```

The download endpoint returns the stored result using the correct file extension and content type.

## 4. Poll with `/content/Status/{id}` While Waiting

`/documents/{id}` only returns a result after the document has been generated successfully. While the request is still running, use `/content/Status/{id}`:

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

**Tips**

* Treat `/content/Status/{id}` as the job-status API.
* Treat `/documents/get` and `/documents/{id}` as the document library API.
* For `pdf`, you can either read `document_url` from the status response or `url` from `/documents/{id}`.

## Try it in code

* [C#](/code-samples/documents/csharp/retrieve-and-download)
* [Node.js](/code-samples/documents/nodejs/retrieve-and-download)
* [Java](/code-samples/documents/java/retrieve-and-download)
* [PHP](/code-samples/documents/php/retrieve-and-download)
* [Python](/code-samples/documents/python/retrieve-and-download)


# Quizzes


# Quiz Scenario Examples

Focused `curl` samples for generating quizzes. Each recipe uses `/content/Create` with `outputType: "quiz"` and highlights how to set difficulty, language, and prompts.

## Available Recipes

* [📝 Create a Quiz from Text](/quick-start/quizzes/from-text)
* [🔗 Create a Quiz from a Website](/quick-start/quizzes/from-website)
* [🎚️ Set Difficulty and Language](/quick-start/quizzes/set-difficulty-and-language)
* [💡 Create a Quiz from a Topic Prompt](/quick-start/quizzes/from-topic)
* [🏢 Apply Brand Settings with `projectId`](/quick-start/quizzes/brand-with-project-id)

Start with the text recipe, then add sources or difficulty tweaks as needed.


# Create a Quiz from Text

Generate a quiz by combining a text resource with explicit instructions.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "quiz",
    "resources": [
      { "type": "text", "content": "Key takeaways from our 2024 SaaS pricing study." }
    ],
    "text": "Create an 8-question multiple-choice quiz with 4 options each.",
    "quizDifficulty": "medium"
  }'
```

**Tips**

* Use `quizDifficulty` (`easy`, `medium`, `hard`) to control how challenging the questions feel.
* Keep `text` short and directive to steer question style and count.


# Create a Quiz from a Website

Feed a URL into the quiz generator to turn a report into knowledge checks.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "quiz",
    "resources": [
      { "type": "website", "content": "https://example.com/2024-market-report" }
    ],
    "text": "Focus on the headline stats and include 2 scenario questions.",
    "quizDifficulty": "easy"
  }'
```

**Tips**

* Pair a `website` resource with a short `text` brief to spotlight specific angles.
* Use `easy` for onboarding quizzes and `hard` for certification-style checks.


# Set Difficulty and Language

Override difficulty and language to tune the quiz experience without changing sources.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "quiz",
    "topic": "Cybersecurity basics for remote teams",
    "text": "Create 6 questions with a mix of recall and applied scenarios.",
    "quizDifficulty": "hard",
    "language": "español"
  }'
```

**Tips**

* `language` accepts ISO language names (for example `en`, `es`, `fr`).
* `quizDifficulty` changes the depth of reasoning, not the number of questions.


# Create a Quiz from a Topic Prompt

Let the service research a topic and build quiz questions automatically. Provide a `topic` and optional `text` for extra guidance.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "quiz",
    "topic": "Trends in renewable energy storage",
    "text": "Write 10 questions aimed at college-level students.",
    "quizDifficulty": "medium"
  }'
```

**Tips**

* Add `text` to define audience and tone.
* Use `quizDifficulty` to adjust how challenging the questions are.

## Try it in code

* [C#](/code-samples/quizzes/csharp/from-topic)
* [Node.js](/code-samples/quizzes/nodejs/from-topic)
* [Java](/code-samples/quizzes/java/from-topic)
* [PHP](/code-samples/quizzes/php/from-topic)
* [Python](/code-samples/quizzes/python/from-topic)


# Apply Brand Settings with projectId

Use the `projects` array (one or more project IDs) to apply stored brand settings to quiz outputs. Add it to `/content/Create` with `outputType: "quiz"`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "quiz",
    "projects": ["YOUR_PROJECT_ID"],
    "topic": "Customer success onboarding playbook",
    "text": "Focus on product milestones and include 1 trick question.",
    "quizDifficulty": "medium"
  }'
```

**What `projects` does**

* Pulls your saved brand package to attach consistent metadata to the quiz request.
* Works with any input type (topic, website, text) and all difficulty settings.

Poll `/content/Status/{id}` to fetch the quiz JSON when it completes.

## Try it in code

* [C#](/code-samples/quizzes/csharp/brand-with-project-id)
* [Node.js](/code-samples/quizzes/nodejs/brand-with-project-id)
* [Java](/code-samples/quizzes/java/brand-with-project-id)
* [PHP](/code-samples/quizzes/php/brand-with-project-id)
* [Python](/code-samples/quizzes/python/brand-with-project-id)


# Data Tables


# Create a Data Table

Generate spreadsheet-ready data tables by calling `/content/Create` with `outputType: "datatable"`. Data table jobs are asynchronous: submit the job, poll `/content/Status/{id}`, then download the completed spreadsheet from `/data-tables/{id}/download`.

## Step 1: Create the Data Table Request

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "datatable",
    "resources": [
      {
        "type": "website",
        "content": "https://example.com/market-report"
      }
    ],
    "text": "Extract the named companies, market segment, funding stage, region, and one-sentence positioning into a clean comparison table.",
    "language": "English"
  }'
```

Example response:

```json
{
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0
}
```

Save the `request_id`. It is also the data table ID used by the `/data-tables` endpoints.

## Step 2: Poll for Status

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/550e8400-e29b-41d4-a716-446655440000" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

While processing, treat any `status` from `1` to `99` as still running.

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 80,
  "updated_on": "2026-03-11T19:10:00Z",
  "error_code": 0,
  "requested_on": "2026-03-11T19:08:00Z"
}
```

## Step 3: Read the Completed Status Payload

When `status` reaches `100`, the status response exposes the generated file URL in both `datatable_url` and `share_url`.

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 100,
  "audio_url": "",
  "video_url": "",
  "image_url": "",
  "response_text": "",
  "requested_on": "2026-03-11T19:08:00Z",
  "updated_on": "2026-03-11T19:12:00Z",
  "request_type_id": 1,
  "error_code": 0,
  "error_on": null,
  "citations": [],
  "file_size": 0,
  "audio_duration": 0,
  "share_url": "https://autocontentapi.blob.core.windows.net/audios/datatable-550e8400.xlsx",
  "datatable_url": "https://autocontentapi.blob.core.windows.net/audios/datatable-550e8400.xlsx"
}
```

Use `datatable_url` when you only need the hosted file URL. Use the authenticated download endpoint below when you want the API to verify ownership and stream the file with download headers.

## Step 4: Use the Data Tables API

### List Data Tables

```bash
curl -X GET "https://api.autocontentapi.com/data-tables/get?page=1&pageSize=10" \
  -H "accept: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

Example response:

```json
{
  "items": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "url": "https://autocontentapi.blob.core.windows.net/audios/datatable-550e8400.xlsx",
      "createdOn": "2026-03-11T19:12:00Z",
      "status": 100
    }
  ],
  "totalCount": 1,
  "page": 1,
  "pageSize": 10,
  "totalPages": 1
}
```

The list includes in-progress data table requests. In-progress rows have `status` below `100` and `url: null`.

### Download a Data Table

```bash
curl -L "https://api.autocontentapi.com/data-tables/550e8400-e29b-41d4-a716-446655440000/download" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -o generated-table.xlsx
```

The API streams the generated spreadsheet as an attachment. The file extension is inferred from the stored asset and content type, usually `.xlsx`.

## Supported Source Types

Data tables use the same source model as the general content endpoint:

| Type      | Description                  | Example                                      |
| --------- | ---------------------------- | -------------------------------------------- |
| `website` | Public web page URL          | `"https://example.com/report"`               |
| `youtube` | YouTube video URL            | `"https://www.youtube.com/watch?v=VIDEO_ID"` |
| `text`    | Direct text source material  | `"Company A raised $10M..."`                 |
| `pdf`     | Base64-encoded PDF payload   | `"BASE64_ENCODED_PDF"`                       |
| `file`    | File ID returned by `/files` | `"YOUR_FILE_ID"`                             |

You can also use `topic`, `feedSelections`, `researches`, `podcastEpisodeIds`, and `projects` when those sources are available in your account.

## Prompting Tips

1. Name the columns you want in `text`.
2. Ask for normalized values when the source has inconsistent labels.
3. Use a source with enough structured facts; data table generation works best when the input contains comparable entities, dates, metrics, categories, or rankings.
4. Poll `/content/Status/{id}` before downloading. `/data-tables/{id}/download` returns `404` until the asset is ready.

## Error Handling

If generation fails, `/content/Status/{id}` returns the same error metadata used by other asynchronous content jobs:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0,
  "error_code": 500,
  "error_message": "Unable to process this request right now. Please try again.",
  "error_on": "2026-03-11T19:09:30Z",
  "requested_on": "2026-03-11T19:08:00Z"
}
```

## What's Next?

* 📋 Browse the [Data Table Scenario Examples](/quick-start/data-tables/data-table-examples)
* 🧭 Review [Track Requests & Status Codes](/quick-start/tools/track-requests)
* 📁 Upload private source files with [Upload Private Files](/quick-start/tools/upload-files)


# Data Table Scenario Examples

Copy-paste `curl` recipes for building spreadsheet-ready tables with `/content/Create` and `outputType: "datatable"`.

## Available Recipes

* [📝 Create a Data Table from Text](/quick-start/data-tables/from-text)
* [🔗 Create a Data Table from a Website](/quick-start/data-tables/from-website)
* [💡 Create a Data Table from a Topic Prompt](/quick-start/data-tables/from-topic)
* [🔬 Create a Data Table from Deep Research Results](/quick-start/data-tables/from-research)

Start with the text recipe when you already have structured facts. Use website or research inputs when AutoContent should extract the facts first.


# Create a Data Table from Text

Turn pasted source material into a spreadsheet file.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "datatable",
    "resources": [
      {
        "type": "text",
        "content": "Company A raised $12M in Series A funding in Spain. Company B raised $35M in Series B funding in France. Company C bootstrapped in Germany and focuses on supply-chain AI."
      }
    ],
    "text": "Create columns for company, country, funding stage, funding amount, and positioning notes."
  }'
```

**Tips**

* Put raw facts in `resources`.
* Put column instructions and normalization rules in `text`.
* Poll `/content/Status/{id}` and download with `/data-tables/{id}/download`.


# Create a Data Table from a Website

Extract structured facts from a public page.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "datatable",
    "resources": [
      {
        "type": "website",
        "content": "https://example.com/ai-vendor-landscape"
      }
    ],
    "text": "Build a vendor comparison table with columns for vendor, category, target customer, notable feature, pricing signal, and source note."
  }'
```

**Tips**

* Use one focused page or report URL when possible.
* If the page is long, describe the exact entities or metrics to extract in `text`.


# Create a Data Table from a Topic Prompt

Use `topic` when you want AutoContent to research and structure a table around a subject.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "datatable",
    "topic": "European AI infrastructure startups",
    "text": "Create a comparison table with startup, headquarters, product category, buyer persona, funding stage, and one notable risk."
  }'
```

**Tips**

* Keep `topic` under 500 characters.
* Use `text` to define columns, sort order, and what counts as a relevant row.


# Create a Data Table from Deep Research Results

Reuse completed deep research output as the source for a spreadsheet.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "datatable",
    "researches": [
      "RESEARCH_REQUEST_ID"
    ],
    "text": "Convert the research into a ranked table with columns for company, category, evidence, momentum signal, risk, and recommended follow-up."
  }'
```

**Tips**

* `researches` accepts up to 10 completed research IDs.
* This is useful when you need a spreadsheet handoff after a narrative research workflow.


# Slide Decks


# Slide Deck Scenario Examples

Copy-paste payloads for building slideware with `/content/Create` and `outputType: "slide_deck"`. These recipes show how to feed source material, pick formats, and control length.

## Available Recipes

* [📝 Create a Slide Deck from Text](/quick-start/slide-decks/from-text)
* [🔗 Create a Slide Deck from a Website](/quick-start/slide-decks/from-website)
* [🎤 Presenter Notes Format](/quick-start/slide-decks/set-presenter-format)
* [💡 Create a Slide Deck from a Topic Prompt](/quick-start/slide-decks/from-topic)
* [🏢 Apply Brand Logo with `projectId`](/quick-start/slide-decks/brand-with-project-id)

Start with the text recipe, then experiment with formats (`detailed` vs. `presenter`) to match your audience.


# Create a Slide Deck from Text

Turn written prompts into a structured deck with slide headlines, bullets, and speaker notes.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "slide_deck",
    "resources": [
      { "type": "text", "content": "Internal memo on the new analytics rollout, timeline, and launch messaging." }
    ],
    "text": "Build a 10-slide deck with an executive summary, timeline, risks, and next steps.",
    "duration": "default",
    "slideDeckFormat": "detailed"
  }'
```

**Tips**

* Use `duration` to control depth: `short` for quick briefings, `long` for full project reviews.
* `slideDeckFormat` of `detailed` includes bullets per slide; switch to `presenter` for leaner slides plus speaking notes.


# Create a Slide Deck from a Website

Feed a URL to build a slide deck that highlights the main stats and takeaways.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "slide_deck",
    "resources": [
      { "type": "website", "content": "https://example.com/case-study" }
    ],
    "text": "Create a client-ready case study deck with problem, solution, results, and a final CTA slide.",
    "duration": "long",
    "slideDeckFormat": "detailed"
  }'
```

**Tips**

* Combine multiple resources (website + PDF + text) to enrich the deck outline.
* Keep `text` focused on the intended audience and call-to-action so the slides stay on-message.


# Presenter Notes Format

Switch to the presenter-focused layout when you want lean slides backed by richer notes.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "slide_deck",
    "topic": "Migrating a monolith to microservices",
    "text": "Keep slides minimal with talking points in presenter notes. Close with a checklist.",
    "duration": "short",
    "slideDeckFormat": "presenter"
  }'
```

**Tips**

* `slideDeckFormat` accepts `detailed` (heavier slides) or `presenter` (lighter slides + notes).
* Pair `presenter` with `duration: \"short\"` for lightning talks, or `long` to flesh out full workshops.


# Create a Slide Deck from a Topic Prompt

Let the API draft a deck outline from a high-level subject. Include `text` to set the audience, call-to-action, or structure, and toggle `slideDeckFormat` to control density.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "slide_deck",
    "topic": "Best practices for onboarding remote employees",
    "text": "Target startup HR teams with a concise 8-slide plan and one checklist slide.",
    "duration": "default",
    "slideDeckFormat": "presenter"
  }'
```

**Tips**

* Switch `slideDeckFormat` between `presenter` (lean slides plus notes) and `detailed` (heavier bullets per slide).
* Use `duration` (`short`, `default`, `long`) to stretch or compress the slide count and detail.
* Add a call-to-action in `text` to shape closing slides.

## Try it in code

* [C#](/code-samples/slide-decks/csharp/from-topic)
* [Node.js](/code-samples/slide-decks/nodejs/from-topic)
* [Java](/code-samples/slide-decks/java/from-topic)
* [PHP](/code-samples/slide-decks/php/from-topic)
* [Python](/code-samples/slide-decks/python/from-topic)


# Apply Brand Logo with projectId

Attach your stored brand assets (logos, marks) to slide deck outputs by adding the `projects` array to `/content/Create` with `outputType: "slide_deck"`. Need a project first? Follow [Create a Project (Brand Assets)](/quick-start/tools/create-project) to save a logo via `imageUrl` or `imageData`.

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "slide_deck",
    "projects": ["YOUR_PROJECT_ID"],
    "topic": "Annual security posture update",
    "text": "Executive-level slides with KPIs, risks, mitigations, and a closing CTA.",
    "duration": "default",
    "slideDeckFormat": "detailed"
  }'
```

**What `projects` does**

* Pulls your saved brand package to place the logo and styling in the generated slides.
* Works alongside other deck controls (`slideDeckFormat`, `duration`, language, style).

Poll `/content/Status/{id}` to download the branded deck when status reaches `100`.

## Try it in code

* [C#](/code-samples/slide-decks/csharp/brand-with-project-id)
* [Node.js](/code-samples/slide-decks/nodejs/brand-with-project-id)
* [Java](/code-samples/slide-decks/java/brand-with-project-id)
* [PHP](/code-samples/slide-decks/php/brand-with-project-id)
* [Python](/code-samples/slide-decks/python/brand-with-project-id)


# Video Shorts


# Create a Video Short

Learn how to generate AI-powered video shorts with talking avatars from text content, perfect for social media and educational content.

## Step 1: Get Available Avatars

First, see what avatars are available for your video by calling `/video/GetAvatars`:

```bash
curl -X GET "https://api.autocontentapi.com/video/GetAvatars" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Example Response

```json
[
  {
    "id": "1",
    "name": "Professional Woman",
    "gender": "F"
  },
  {
    "id": "2", 
    "name": "Business Man",
    "gender": "M"
  },
  {
    "id": "3",
    "name": "Casual Speaker",
    "gender": "F"
  }
]
```

**Important:** Choose avatar IDs for your video - you'll need at least one!

To change an avatar's narration voice, pass a numeric `voiceId` from `/content/GetVoices`:

```bash
curl -X POST "https://api.autocontentapi.com/video/UpdateAvatarVoice" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "avatarId": 1,
    "voiceId": 13
  }'
```

## Step 2: Create Video Short from Text

Use `/video/CreateShortsFromContent` to generate a video short from text content:

```bash
curl -X POST "https://api.autocontentapi.com/video/CreateShortsFromContent" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Welcome to our AI tutorial series! Today we will explore the fascinating world of machine learning and how it is transforming businesses across every industry. From predictive analytics to natural language processing, AI is creating unprecedented opportunities for innovation.",
    "avatar1": "1",
    "avatar2": "2", 
    "subtitles": true,
    "prompt": "Create an engaging educational video about AI and machine learning for business professionals"
  }'
```

### Request Parameters

| Parameter      | Description                     | Required | Options                            |
| -------------- | ------------------------------- | -------- | ---------------------------------- |
| `text`         | Content for the video           | Yes      | Any text content                   |
| `avatar1`      | Primary avatar ID               | Yes      | Avatar ID from `/video/GetAvatars` |
| `avatar2`      | Secondary avatar ID             | No       | Avatar ID for dialogue format      |
| `subtitles`    | Include subtitles               | No       | `true`/`false` (default: `true`)   |
| `prompt`       | Instructions for video creation | No       | Any guidance text                  |
| `callbackData` | Optional callback data          | No       | Any string                         |
| `scheduledOn`  | Schedule for later              | No       | ISO datetime                       |

Use [Track Requests & Status Codes](/quick-start/tools/track-requests) for the shared polling flow, request ID patterns, and `callbackData` guidance.

### Example Response

```json
{
  "requestId": "video-550e8400-e29b-41d4-a716-446655440000",
  "status": 0
}
```

## Step 3: Poll Video Status

Check the video generation progress using `/content/Status/{id}`:

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/video-550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### While Processing

```json
{
  "id": "video-550e8400-e29b-41d4-a716-446655440000",
  "status": 5,
  "updated_on": "2024-01-15T10:32:00Z",
  "error_code": 0,
  "requested_on": "2024-01-15T10:30:00Z"
}
```

**Status Codes:**

* `0` = Pending (queued for processing)
* `5` = Processing (video generation in progress)
* `100` = Completed (video ready!)

## Step 4: Get Your Video Short

When `status` reaches `100`, your video is ready:

```json
{
  "id": "video-550e8400-e29b-41d4-a716-446655440000",
  "audio_title": "AI Tutorial: Machine Learning for Business",
  "status": 100,
  "audio_url": "https://storage.autocontentapi.com/audio/video-550e8400-e29b-41d4-a716-446655440000.mp3",
  "video_url": "https://storage.autocontentapi.com/video/video-550e8400-e29b-41d4-a716-446655440000.mp4",
  "response_text": "Welcome to our AI tutorial series! Today we will explore...",
  "requested_on": "2024-01-15T10:30:00Z",
  "updated_on": "2024-01-15T10:35:00Z",
  "request_type_id": 4,
  "error_code": 0,
  "file_size": 45234567,
  "share_url": "https://autocontentapi.com/share/video-550e8400-e29b-41d4-a716-446655440000"
}
```

**🎉 Success!** Your video short is ready at the `video_url`!

## Alternative Methods

### Method 2: Create from Audio Content

If you already have audio content, use `/video/CreateShorts`:

```bash
curl -X POST "https://api.autocontentapi.com/video/CreateShorts" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "audioUrl": "https://storage.autocontentapi.com/audio/existing-podcast.mp3",
    "avatar1": "1",
    "avatar2": "2",
    "subtitles": true,
    "prompt": "Create a professional business presentation style video"
  }'
```

### Method 3: Create from Custom Script

For precise control, use `/video/CreateShortsFromScript` with dialogue format:

```bash
curl -X POST "https://api.autocontentapi.com/video/CreateShortsFromScript" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "script": [
      {
        "avatarId": 1,
        "text": "Hello everyone, welcome to our AI series!"
      },
      {
        "avatarId": 2, 
        "text": "Today we will explore machine learning fundamentals."
      },
      {
        "avatarId": 1,
        "text": "Let us start with the basics of neural networks."
      }
    ],
    "subtitles": true
  }'
```

Each script line is assigned to the `avatarId` on that line. If an avatar has lip sync disabled, the renderer still keeps speaker-specific avatar segments and subtitles aligned to the script instead of collapsing the dialogue into a single avatar track.

### Method 4: Create from Deep Research

Convert research findings into video content using `/video/CreateShortsFromDeepResearch`:

```bash
curl -X POST "https://api.autocontentapi.com/video/CreateShortsFromDeepResearch" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "deepResearchId": "550e8400-e29b-41d4-a716-446655440000",
    "avatar1": "1",
    "avatar2": "2",
    "subtitles": true,
    "prompt": "Create an educational video explaining the research findings in simple terms"
  }'
```

## View Your Video Shorts

Get all your created video shorts:

```bash
curl -X GET "https://api.autocontentapi.com/video/GetShorts" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Response

```json
[
  {
    "id": "video-550e8400-e29b-41d4-a716-446655440000",
    "status": 100,
    "requestedOn": "2024-01-15T10:30:00Z",
    "processingOn": "2024-01-15T10:31:00Z", 
    "succeededOn": "2024-01-15T10:35:00Z",
    "requestTypeId": 4,
    "callbackData": "ai-tutorial-video",
    "audioUrl": "https://storage.autocontentapi.com/audio/video-550e8400-e29b-41d4-a716-446655440000.mp3",
    "audioTitle": "AI Tutorial: Machine Learning for Business",
    "responseText": "Welcome to our AI tutorial series..."
  }
]
```

## Avatar Selection Tips

### Single Avatar (Presentation Style)

* Use only `avatar1` for lecture/presentation format
* Great for educational content, tutorials, announcements
* More focused, single-speaker delivery

### Dual Avatar (Conversation Style)

* Use both `avatar1` and `avatar2` for dialogue format
* Perfect for interviews, debates, Q\&A sessions
* Creates more engaging, conversational content

### Gender Considerations

* Mix genders (`"M"` and `"F"`) for diverse representation
* Consider your target audience preferences
* Professional vs. casual avatar styles

## Content Types That Work Well

### Educational Content

```json
{
  "text": "In this video, we'll explain the key principles of blockchain technology and how it enables secure, decentralized transactions across networks.",
  "prompt": "Create an educational explainer video with clear, simple language"
}
```

### Product Announcements

```json
{
  "text": "We're excited to announce the launch of our new AI-powered customer service platform that reduces response times by 90%.",
  "prompt": "Create an enthusiastic product announcement video"
}
```

### Tutorial Content

```json
{
  "text": "Step 1: Open your dashboard. Step 2: Click on Analytics. Step 3: Select your date range. Step 4: Export your data.",
  "prompt": "Create a step-by-step tutorial video with clear instructions"
}
```

### Marketing Content

```json
{
  "text": "Transform your business with AI automation. Increase efficiency, reduce costs, and scale faster than ever before.",
  "prompt": "Create a compelling marketing video with energetic delivery"
}
```

## Best Practices

### Content Length

* **Optimal:** 30-90 seconds for social media
* **Maximum:** 3-5 minutes for detailed explanations
* **Minimum:** 15 seconds for quick announcements

### Text Guidelines

* **Clear Structure:** Use bullet points or numbered steps
* **Conversational Tone:** Write as you would speak
* **Call to Action:** End with clear next steps
* **Keyword Rich:** Include relevant terms for SEO

### Visual Considerations

* **Subtitles:** Always enable (default `true`) for accessibility
* **Avatar Choice:** Match avatar style to content tone
* **Prompt Instructions:** Guide the delivery style and energy

## Error Handling

### Invalid Avatar ID

```json
{
  "error": "Invalid avatar ID provided",
  "status": 400
}
```

### Text Too Long

```json
{
  "error": "Text content exceeds maximum length",
  "status": 400
}
```

### Processing Failed

```json
{
  "id": "video-550e8400-e29b-41d4-a716-446655440000",
  "status": 0,
  "error_code": 500,
  "error_message": "Video generation failed, please try again",
  "updated_on": "2024-01-15T10:35:00Z"
}
```

## Use Cases

**Social Media Marketing:** Create engaging shorts for Instagram, TikTok, YouTube Shorts

**Employee Training:** Generate training videos for onboarding and skill development

**Product Demos:** Show features and benefits with professional avatars

**Educational Content:** Create course materials and explainer videos

**Customer Support:** Build FAQ videos with common questions and answers

**Internal Communications:** Company updates and announcements

## What's Next?

* 🎧 Learn about [Creating Podcast Episodes](/quick-start/podcasts/create-podcast-episode) for audio content
* 🐦 Explore [Creating Content from X Feeds](/quick-start/podcasts/create-feed-podcast)
* 🔬 Try [Deep Research Podcasts](/quick-start/deep-researches/create-research-podcast) for comprehensive content
* 📖 Check out more [Code Samples](/code-samples) in different languages
* 🗣️ Discover [Custom Voices](/voices) for audio content
* ❓ Have questions? Visit our [FAQ](/faq)


# Deep Researches


# Start Deep Research

Collect long-form insights and analysis ready for podcasts, posts, or briefing packs. This guide mirrors the AutoContent app flow so you can submit research, monitor progress, and hand the results off to other tools.

## Before You Begin

* Configure your API key under `Settings`; the research pages hide until authentication succeeds.
* Decide whether you want a one-off briefing or a recurring digest so you can set frequency up front.
* Keep in mind that each request consumes credits (Gemini: 100, OpenAI: 200) even when you run them in bulk.

## Step 1: Open the Research Composer

1. In the sidebar, choose `Deep Research -> Researches`.
2. Click `New Research` in the header to launch the composer at `/research/create`.

If you are migrating multiple prompts, you can jump straight into bulk mode using the toggle in the top-right corner of the form (details below).

## Step 2: Craft Your Prompt

In single-request mode, complete the following fields:

| Field          | Required | Description                                                                                                        |
| -------------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
| Research Query | ✅        | The question or topic to investigate; add context, time frames, or desired angles for richer output.               |
| AI Provider    | ✅        | Choose between `Gemini` (default) or `OpenAI` depending on the analysis style you prefer.                          |
| Recurring      | Optional | Toggle on to run the same request automatically. Once active, set `Times per day` (1-24) and an optional end date. |

Use the prompt description beneath the text area as a checklist; the app surfaces guardrails (for example, missing prompts) before it sends the request.

## Step 3: Submit and Track

Click `New Research`. The button locks while the request is in flight and flips to a loader so you know it succeeded. Behind the scenes the app performs:

```bash
curl -X POST "https://api.autocontentapi.com/deep-research/research" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "text": "What are the latest developments in climate tech policy?",
    "outputType": "text",
    "provider": "gemini"
  }'
```

When you enable the recurring toggle, the payload also includes `"isScheduled": true`, `"dailyCount": <1-24>`, and, if specified, an ISO-formatted `"scheduleEndDate"`.

Successful responses immediately appear inside the `Researches` list with status `0` or `5`. The app automatically refreshes in the background until each item reaches `100` (complete) or reports an error. You can always click the `Refresh` icon in the list header to force an update.

## Step 4: Review Results in Researches

Back on `/research` you get a filtered dashboard:

* Use the status tabs (`All`, `Completed`, `Processing`, `Failed`) and search bar to zero in on the right request.
* Select a research item to view its full transcript, copy the rundown as rich HTML or clean text, or retry a failed job.
* Launch `Create podcast` from a completed research to pre-fill the episode workflow described in [Create a Podcast Episode from Deep Research](/quick-start/deep-researches/create-research-podcast).
* Multi-select several items to send them to the bulk podcast builder, schedule them, or export transcripts.

## Step 5: Run Bulk Research (Optional)

Need dozens of summaries at once? Toggle `Switch to bulk mode` from the composer header:

1. Paste one prompt per line into the bulk textarea.
2. Pick the provider and (optionally) enable recurring just like in single mode.
3. Click `Start Bulk Research` and confirm the number of requests. The app queues each call sequentially with a 15-second pause to respect rate limits and shows a live progress counter.

Once finished, successes and failures are tallied in the confirmation banner, and all completed runs land inside the main `Researches` list for follow-up.

## Step 6: Move Results into Shows and Episodes

Deep research is most powerful when paired with audio:

* Open any completed research and choose `Create podcast` to jump into the episode builder with the research ID preloaded.
* Inside the episode form you can also pick a `Podcast Show` (created via [Create a Podcast Show](broken://pages/BT3bjKZ3SZ4Ra5TbP1Ug)) so the finished audio drops straight into the right RSS feed.

## Common API Endpoints

* `POST /deep-research/research` - Submit a new single or scheduled research job.
* `GET /deep-research/research` - List all research requests and their statuses.
* `GET /deep-research/research/{id}` - Poll a specific request if you need tighter control over refresh intervals.

## What's Next?

* Turn a finished briefing into audio with [Create a Podcast Episode from Deep Research](/quick-start/deep-researches/create-research-podcast).
* Sync the resulting audio to an RSS feed using [Create a Podcast Show](broken://pages/BT3bjKZ3SZ4Ra5TbP1Ug).
* Explore the `Recurring` tab under `Deep Research -> Researches` to templatise daily or weekly digests.


# Create a Podcast Episode from Deep Research

Learn how to perform advanced research on any topic and use the results to generate comprehensive AI-powered podcast episodes.

> Need help generating research IDs from the app? Follow [Start Deep Research](/quick-start/deep-researches/start-deep-research) to create and manage your deep research requests before you continue here.

## Step 1: Create Deep Research Request

Start by creating a deep research request using `/deep-research/research`:

```bash
curl -X POST "https://api.autocontentapi.com/deep-research/research" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "What are the latest developments in artificial intelligence and machine learning in 2024?",
    "outputType": "text",
    "provider": "gemini",
    "callbackData": "ai-research-2024"
  }'
```

### Request Parameters

| Parameter      | Description            | Required | Options                                      |
| -------------- | ---------------------- | -------- | -------------------------------------------- |
| `text`         | The research query     | Yes      | Any research question                        |
| `outputType`   | Format of results      | Yes      | `"text"`                                     |
| `provider`     | AI provider to use     | No       | `"gemini"`, `"openai"` (default: `"gemini"`) |
| `callbackData` | Optional callback data | No       | Any string                                   |

Use [Track Requests & Status Codes](/quick-start/tools/track-requests) for the shared async flow, `request_id` handling, and `callbackData` guidance.

### Example Response

```json
{
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

**Important:** Save the `request_id` - you'll need it to check research status and create your podcast!

## Step 2: Poll Research Status

Check the research progress using `/deep-research/research/{id}`:

```bash
curl -X GET "https://api.autocontentapi.com/deep-research/research/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### While Processing

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "requestedOn": "2024-01-15T10:30:00Z",
  "status": 5,
  "errorOn": null,
  "errorMessage": null,
  "errorCode": 0,
  "prompt": "What are the latest developments in artificial intelligence and machine learning in 2024?"
}
```

### Research Completed

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "requestedOn": "2024-01-15T10:30:00Z",
  "succeededOn": "2024-01-15T10:35:00Z",
  "status": 100,
  "errorOn": null,
  "errorMessage": null,
  "errorCode": 0,
  "prompt": "What are the latest developments in artificial intelligence and machine learning in 2024?",
  "responseText": "Based on extensive research, here are the key developments in AI and ML for 2024..."
}
```

**Research Status Codes:**

* `0` = Pending (queued for research)
* `5` = Processing (research in progress)
* `100` = Completed (research ready!)

## Step 3: Create Podcast from Research

Once research status is `100`, use the research ID to create a podcast:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "researches": ["550e8400-e29b-41d4-a716-446655440000"],
    "outputType": "audio",
    "text": "Create an engaging podcast discussion based on this comprehensive research about AI developments",
    "duration": "long"
  }'
```

### Example Response

```json
{
  "request_id": "research-podcast-550e8400-e29b-41d4-a716-446655440001",
  "status": 0
}
```

## Step 4: Poll Podcast Status

Check the podcast generation progress:

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/research-podcast-550e8400-e29b-41d4-a716-446655440001" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### While Processing

```json
{
  "id": "research-podcast-550e8400-e29b-41d4-a716-446655440001",
  "status": 5,
  "updated_on": "2024-01-15T10:40:00Z",
  "error_code": 0,
  "requested_on": "2024-01-15T10:38:00Z"
}
```

## Step 5: Get Your Research-Based Podcast

When `status` reaches `100`, your comprehensive podcast is ready:

```json
{
  "id": "research-podcast-550e8400-e29b-41d4-a716-446655440001",
  "audio_title": "Deep Dive: AI and ML Developments in 2024",
  "status": 100,
  "audio_url": "https://storage.autocontentapi.com/audio/research-podcast-550e8400-e29b-41d4-a716-446655440001.mp3",
  "response_text": "Full transcript of the comprehensive discussion based on deep research findings...",
  "requested_on": "2024-01-15T10:38:00Z",
  "updated_on": "2024-01-15T10:45:00Z",
  "request_type_id": 1,
  "error_code": 0,
  "file_size": 25234567,
  "audio_duration": 1234.56,
  "share_url": "https://autocontentapi.com/share/research-podcast-550e8400-e29b-41d4-a716-446655440001"
}
```

**🎉 Success!** Your research-based podcast is ready with comprehensive, well-researched content!

## Managing Your Research

### List All Your Research Requests

```bash
curl -X GET "https://api.autocontentapi.com/deep-research/research" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Get Specific Research Details

```bash
curl -X GET "https://api.autocontentapi.com/deep-research/research/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

## Advanced: Multiple Research Sources

You can combine multiple research results in a single podcast:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "researches": [
      "550e8400-e29b-41d4-a716-446655440000",
      "550e8400-e29b-41d4-a716-446655440001",
      "550e8400-e29b-41d4-a716-446655440002"
    ],
    "outputType": "audio",
    "text": "Create a comprehensive podcast combining insights from all these research findings",
    "duration": "long"
  }'
```

**Note:** Maximum of 10 research IDs per request.

## Research Query Ideas

### Technology Research

```json
{
  "text": "What are the breakthrough innovations in quantum computing and their practical applications?",
  "outputType": "text",
  "provider": "gemini"
}
```

### Business & Economics

```json
{
  "text": "How is artificial intelligence transforming the financial services industry in 2024?",
  "outputType": "text",
  "provider": "openai"
}
```

### Science & Health

```json
{
  "text": "What are the latest developments in personalized medicine and gene therapy?",
  "outputType": "text",
  "provider": "gemini"
}
```

### Market Analysis

```json
{
  "text": "What are the emerging trends in renewable energy technology and market adoption?",
  "outputType": "text",
  "provider": "gemini"
}
```

## Error Handling

### Research Request Errors

```json
{
  "success": false,
  "error": "Invalid research query provided"
}
```

### Research Failed

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0,
  "errorOn": "2024-01-15T10:32:00Z",
  "errorMessage": "Research query too broad, please be more specific",
  "errorCode": 400
}
```

### Podcast Creation with Invalid Research ID

```json
{
  "error": "Research ID not found or not accessible",
  "status": 400
}
```

## Benefits of Research-Based Podcasts

**Comprehensive Coverage:** Deep research provides thorough analysis of complex topics

**Current Information:** Research pulls from the latest available sources and data

**Multiple Perspectives:** Research synthesizes information from various authoritative sources

**Fact-Checked Content:** Research process includes verification and cross-referencing

**Professional Quality:** Research-based podcasts sound more authoritative and well-informed

## Use Cases

**Educational Content:** Create in-depth educational podcasts on complex subjects

**Industry Reports:** Generate comprehensive industry analysis and trend reports

**Investment Research:** Create detailed market analysis and investment insights

**Academic Discussions:** Transform complex research topics into accessible audio content

**Expert Interviews Prep:** Use research as background for preparing interview questions

## Research Tips

1. **Be Specific:** More focused queries yield better research results
2. **Use Keywords:** Include relevant industry terms and specific concepts
3. **Time-Sensitive Topics:** Specify time ranges for current information
4. **Multiple Angles:** Create separate research requests for different aspects of complex topics
5. **Provider Selection:** Try both Gemini and OpenAI to see which works better for your topic

## What's Next?

* 🎧 Learn about [Creating Basic Podcasts](/quick-start/podcasts/create-podcast-episode) from web resources
* 🐦 Explore [Creating Podcasts from X Feeds](/quick-start/podcasts/create-feed-podcast)
* 📖 Check out more [Code Samples](/code-samples) in different languages
* 🗣️ Discover [Custom Voices](/voices) for personalized research podcasts
* ❓ Have questions? Visit our [FAQ](/faq)


# Tools


# Track Requests & Status Codes

Most AutoContent generation endpoints are asynchronous. Submit the job, save the returned request ID exactly as-is, poll the status endpoint, and only read final asset fields once the request reaches `100`.

## Step 1: Save the Request ID

Different endpoints may return the same concept with slightly different field names:

* `request_id`
* `requestId`

Examples:

```json
{
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": 0
}
```

```json
{
  "requestId": "video-550e8400-e29b-41d4-a716-446655440000",
  "status": 0
}
```

Keep the full value unchanged. Some endpoints prefix the ID with the job type, such as `video-...` or `research-podcast-...`.

## Step 2: Poll `/content/Status/{id}`

Use the exact request ID returned by the create call:

```bash
curl -X GET "https://api.autocontentapi.com/content/Status/YOUR_REQUEST_ID" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

Typical in-progress response:

```json
{
  "id": "YOUR_REQUEST_ID",
  "status": 5,
  "updated_on": "2026-03-11T19:10:00Z",
  "error_code": 0,
  "requested_on": "2026-03-11T19:08:00Z"
}
```

## Step 3: Interpret the Status Value

The two stable states are:

* `0`: accepted and queued
* `100`: completed

Intermediate values vary by endpoint. Common examples include:

| Status                             | Meaning           | Where you may see it                           |
| ---------------------------------- | ----------------- | ---------------------------------------------- |
| `5`                                | Early processing  | Podcasts, research-backed flows, several tools |
| `10`, `20`, `30`, `60`, `80`, `90` | Mid-pipeline work | Endpoint-specific generation stages            |

Treat any value between `1` and `99` as "still running" unless the response also includes an error.

## Step 4: Read Success and Error Fields

Once the request reaches `100`, the payload includes output-specific fields. Common ones include:

* `audio_url` for podcast outputs
* `video_url` or similar media URLs for video endpoints
* `document_url` or `briefing_doc_url` for PDF briefing documents
* `document_content` for `html` or `text` briefing documents
* `datatable_url` for generated data table spreadsheets
* `image_url` for generated infographics
* `slide_deck_url` for generated slide decks
* `quiz_json` for generated quizzes
* `response_text` for generated transcript or text content
* `share_url` for hosted result pages

Error metadata can also vary slightly by endpoint. Watch for either:

* `error_code` or `errorCode`
* `error_message` or `errorMessage`

If the response includes a non-zero error value, use [Error Codes](/error-codes) to diagnose the failure before retrying.

## Step 5: Use `callbackData` for Reconciliation

Some endpoints accept an optional `callbackData` field. Use it as your own stable job reference, for example:

* a CMS entry ID
* a campaign or customer ID
* an internal workflow run ID

When a workflow supports webhook notifications, `callbackData` is the safest way to map the incoming event back to your system. Keep it short, machine-readable, and unique per job.

## Endpoint-Specific Notes

* Briefing documents: poll `/content/Status/{id}` first, then use `/documents/{id}` only after the job has completed.
* Data tables: poll `/content/Status/{id}` first, then use `/data-tables/get` for history or `/data-tables/{id}/download` for the spreadsheet.
* Infographics, slide decks, and quizzes: poll `/content/Status/{id}` first, then use their artifact-specific list/download endpoints for authenticated retrieval.
* Deep research: the research creation flow uses `/deep-research/research/{id}` while the downstream content generation still uses `/content/Status/{id}`.
* Tools such as transcription, speaker separation, and voice cloning still follow the same "save ID, poll, read final result" pattern.

## Related Endpoints

* `GET /content/Status/{id}` - Check the status of a generated content request.
* `GET /deep-research/research/{id}` - Check the status of a deep research request.

## What's Next?

* Need a reusable file ID first? Follow [Upload Private Files](/quick-start/tools/upload-files).
* Working with documents? See [Create a Briefing Document](/quick-start/documents/create-document).
* Need troubleshooting details? Review [Error Codes](/error-codes).


# Upload Private Files

Use `/files` when you want to keep a PDF or other source private instead of placing it at a public URL. Upload once, save the returned file ID, and reuse that ID in workflows that accept `type: "file"`.

For schema-level details, see the Files endpoints in the [API Documentation](/).

## Before You Begin

* Have your API token ready (`Authorization: Bearer ...`).
* Uploads use `multipart/form-data`.
* The Files API accepts uploads up to `200 MB`.

## Step 1: Upload the File

```bash
curl -X POST "https://api.autocontentapi.com/files" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "file=@/absolute/path/to/report.pdf"
```

The upload response includes the stored file record. Save its `id` and use that value anywhere a guide asks for `YOUR_FILE_ID`.

## Step 2: List Uploaded Files

Use the list endpoint to confirm the upload, recover an existing file ID, or inspect what is still stored:

```bash
curl -X GET "https://api.autocontentapi.com/files" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

## Step 3: Use the File ID in a Document Request

Briefing document flows can reference the uploaded file directly:

```bash
curl -X POST "https://api.autocontentapi.com/content/Create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outputType": "briefing_doc",
    "format": "html",
    "resources": [
      {
        "type": "file",
        "content": "YOUR_FILE_ID"
      }
    ],
    "text": "Turn this uploaded report into an HTML briefing with headings, bullets, and recommended actions."
  }'
```

After submission, keep the returned request ID and follow [Track Requests & Status Codes](/quick-start/tools/track-requests).

## Step 4: Delete a File You No Longer Need

```bash
curl -X DELETE "https://api.autocontentapi.com/files/YOUR_FILE_ID" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

## Tips

* Use uploaded file IDs when the source document is private or too large for a base64 payload.
* Keep your own mapping between business objects and file IDs if multiple workflows reuse the same uploaded asset.
* For briefing documents, uploaded file IDs are the cleanest way to reference internal PDFs repeatedly without exposing public URLs.

## Related Endpoints

* `POST /files` - Upload a file and receive its file ID.
* `GET /files` - List uploaded files.
* `DELETE /files/{id}` - Remove an uploaded file.

## What's Next?

* Create a document from that asset via [Create a Briefing Document from a PDF Upload](/quick-start/documents/from-pdf).
* Need the broader document flow? See [Create a Briefing Document](/quick-start/documents/create-document).
* Need polling guidance? Review [Track Requests & Status Codes](/quick-start/tools/track-requests).


# Clone a Voice

Capture a custom speaker and reuse that voice across podcasts, shorts, and other AutoContent tools.

## Before You Begin

* Add your API key in `Settings`; the voice cloning page requires authentication.
* Prepare a clean audio recording: at least 10 seconds, single speaker, minimal noise, MP3 or WAV, under 10 MB.
* Decide whether the source lives at a public HTTPS URL or on your machine.

## Step 1: Open the Voice Cloner

1. In the sidebar, go to `Tools -> Clone Voice` (`/tools/clone-voice`).
2. Confirm the banner shows your API key status before proceeding.

## Step 2: Choose the Input Method

Use the toggle at the top of the form to switch between:

* **URL** – Paste a direct HTTPS link to an MP3 or WAV file. The app validates the scheme and common extensions.
* **Upload File** – Select a local audio file. The uploader blocks files above 10 MB and anything that is not audio/\*.

## Step 3: Provide Voice Details

Fill in the required fields:

| Field        | Required | Notes                                                                     |
| ------------ | -------- | ------------------------------------------------------------------------- |
| Voice Name   | Yes      | Friendly label that appears in the voice pickers while creating episodes. |
| Audio Source | Yes      | Either a public URL or uploaded file depending on the selected mode.      |

Use the "Recording Requirements" callout as a checklist: clear speech, single speaker, and natural pacing produce the best clone.

## Step 4: Start the Clone Request

Select **Clone Voice**. The button locks while AutoContent submits the request and displays a success banner with the `request_id` once accepted. Typical processing time is 5-10 minutes.

Want to automate this outside the UI? Toggle **Show API Request** to expose the exact payload. Base requests look like:

```bash
# Clone from a hosted MP3 or WAV
curl -X POST "https://api.autocontentapi.com/content/CloneVoice" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "audioUrl": "https://cdn.example.com/voices/jordan-intro.mp3",
    "name": "Jordan Narrator"
  }'
```

```bash
# Clone from a local file
curl -X POST "https://api.autocontentapi.com/content/CloneVoice" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "audioFile=@/path/to/jordan-intro.wav" \
  -F "name=Jordan Narrator"
```

Responses include:

```json
{
  "request_id": "voice-clone-1234abcd",
  "status": 0
}
```

Track progress on the **Requests** page (`/requests`). When the status reaches `100`, the clone is ready for use.

## Step 5: Use the New Voice in Podcasts

* Open `Podcasts -> Episodes -> New Episode` and expand **Optional Settings**. The cloned voice appears in the voice selectors once processing completes.
* For API calls, run `GET /content/GetVoices` after the clone succeeds and copy the numeric `id` for the cloned voice. Send that number in `voice1`, `voice2`, or `voiceId`; do not send the display name.
* Update existing templates or schedulers to swap in the new voice for future productions.
* Visit the `Voices` page if you want to preview or rename the entry after it is created.

## Related Endpoints

* `POST /content/CloneVoice` – Start voice cloning from a file or URL.
* `GET /content/GetVoices` – List available voices, including custom clones.

## What's Next?

* Pair the cloned voice with fresh audio using [Create a Podcast Episode](/quick-start/podcasts/create-podcast-episode).
* Need more variety? Explore the built-in options in [Voices](/voices).
* Capture supporting research to feed that new host via [Start Deep Research](/quick-start/deep-researches/start-deep-research).




---

[Next Page](/llms-full.txt/1)

