Skip to main content

Episode Management

Manage podcast episodes, transcripts, and generated content.

List Episodes

Retrieve all episodes with metadata and guest information.
GET /api/sanity/episodes
curl https://production.youvebeenheard.com/api/sanity/episodes \
  -H "Cookie: auth_token=<token>"

Response

[
  {
    "_id": "episode_abc123",
    "_type": "episodeContent",
    "_rev": "v1",
    "transcript": "...",
    "prf": "...",
    "viralHooks": "...",
    "metadata": {
      "title": "Episode 385: Chris Pacifico on IT Leadership",
      "guestName": "Chris Pacifico",
      "guestLinkedinUrl": "https://www.linkedin.com/in/chris-pacifico/",
      "episodeNumber": 385,
      "topics": ["IT Leadership", "Vendor Management"],
      "summary": "Chris discusses modern IT leadership challenges"
    },
    "releaseDate": "2024-03-15",
    "socialPosts": {
      "linkedin": ["Post 1", "Post 2"],
      "instagram": [],
      "twitter": []
    },
    "generatedAssets": [],
    "assets": [],
    "videoAssets": [],
    "visualSuggestions": [],
    "scheduledPosts": [],
    "status": "complete",
    "isApproved": false,
    "prfApproved": true,
    "prfApprovedAt": "2024-03-10T10:30:00Z",
    "hooksApproved": true,
    "hooksApprovedAt": "2024-03-10T11:00:00Z",
    "linkedinApproved": false,
    "shareToken": "abc123xyz",
    "shareCreatedAt": "2024-03-10T09:00:00Z",
    "galleryUuid": "gallery_xyz",
    "createdAt": "2024-03-10T08:00:00Z",
    "updatedAt": "2024-03-15T14:30:00Z",
    "guestRef": {
      "_type": "reference",
      "_ref": "guest_123"
    },
    "guest": {
      "_id": "guest_123",
      "name": "Chris Pacifico",
      "linkedinUrl": "https://www.linkedin.com/in/chris-pacifico/",
      "position": "CIO",
      "company": "TechCorp"
    }
  }
]
episodes
array
Array of episode objects, ordered by updatedAt descending

Get Episode

Retrieve a single episode by ID.
GET /api/sanity/episodes/:id
id
string
required
Episode ID
curl https://production.youvebeenheard.com/api/sanity/episodes/episode_abc123 \
  -H "Cookie: auth_token=<token>"

Response

{
  "_id": "episode_abc123",
  "transcript": "Full transcript text...",
  "prf": "PRF document...",
  "viralHooks": "<h2>Hook 1</h2>...",
  "metadata": {
    "title": "Episode 385",
    "guestName": "Chris Pacifico",
    "episodeNumber": 385
  },
  "guest": {
    "_id": "guest_123",
    "name": "Chris Pacifico"
  }
}

Error Responses

StatusErrorDescription
400Episode ID is requiredMissing ID parameter
404Episode not foundEpisode does not exist
401UnauthorizedNot authenticated

Create Episode

Create a new episode with optional transcript and guest reference.
POST /api/sanity/episodes
curl -X POST https://production.youvebeenheard.com/api/sanity/episodes \
  -H "Content-Type: application/json" \
  -H "Cookie: auth_token=<token>" \
  -d '{
    "transcript": "385-Chris Pacifico\nGuest: Chris Pacifico\n...",
    "guestId": "guest_123",
    "metadata": {
      "title": "Episode 385",
      "episodeNumber": 385
    }
  }'

Request

transcript
string
Episode transcript. If provided, metadata will be parsed from header.
guestId
string
Guest ID to link to episode. Guest data will pre-fill metadata.
metadata
object
Episode metadata (optional if guest provided)

Response

{
  "_id": "episode_new123",
  "_type": "episodeContent",
  "transcript": "...",
  "metadata": {
    "title": "Episode 385",
    "guestName": "Chris Pacifico",
    "episodeNumber": 385,
    "topics": [],
    "summary": ""
  },
  "guestRef": {
    "_type": "reference",
    "_ref": "guest_123"
  },
  "status": "draft",
  "isApproved": false,
  "socialPosts": {
    "linkedin": [],
    "instagram": [],
    "twitter": []
  },
  "createdAt": "2024-03-15T10:00:00Z",
  "updatedAt": "2024-03-15T10:00:00Z"
}
Transcript Parsing: If a transcript is provided, the API automatically extracts metadata from the header (episode number, guest name, LinkedIn URL).

Error Responses

StatusErrorDescription
400Invalid JSONRequest body is not valid JSON
400Transcript too largeTranscript exceeds 5MB limit
401UnauthorizedNot authenticated
500Server configuration errorMissing SANITY_API_TOKEN

Update Episode

Update episode fields. Only provided fields are updated.
PATCH /api/sanity/episodes/:id
id
string
required
Episode ID
curl -X PATCH https://production.youvebeenheard.com/api/sanity/episodes/episode_abc123 \
  -H "Content-Type: application/json" \
  -H "Cookie: auth_token=<token>" \
  -d '{
    "prf": "Updated PRF content...",
    "prfApproved": true,
    "prfApprovedAt": "2024-03-15T10:30:00Z"
  }'

Request Fields

All fields are optional. Only include fields you want to update:
transcript
string
Episode transcript
prf
string
PRF (Podcast Repurposing Framework) document
viralHooks
string
Viral hooks HTML content
releaseDate
string
Release date (YYYY-MM-DD format)
metadata
object
Episode metadata (see Create Episode for fields)
sanityPageMetadata
object
Metadata for Sanity podcast episode page
socialPosts
object
Social media posts
status
string
Episode status: draft, in_progress, or complete
prfApproved
boolean
PRF approval status
hooksApproved
boolean
Viral hooks approval status
linkedinApproved
boolean
LinkedIn posts approval status
assets
array
Generated image assets (unified asset storage)

Response

Returns the updated episode object (same structure as Get Episode).

Delete Episode

Delete an episode and remove references from linked guests.
DELETE /api/sanity/episodes/:id
id
string
required
Episode ID
curl -X DELETE https://production.youvebeenheard.com/api/sanity/episodes/episode_abc123 \
  -H "Cookie: auth_token=<token>"

Response

{
  "success": true,
  "id": "episode_abc123",
  "removedFromGuests": 1
}
success
boolean
Deletion status
id
string
Deleted episode ID
removedFromGuests
number
Number of guest records updated to remove episode reference
Permanent Deletion: This action cannot be undone. The episode and all associated data will be permanently removed.

Episode Status Workflow

Episodes progress through these statuses:
StatusDescription
draftEpisode created, no content generated
in_progressPRF or hooks being generated
completeAll content generated and approved

Approval Flags

Each content type has independent approval:
  • prfApproved / prfApprovedAt - PRF document
  • hooksApproved / hooksApprovedAt - Viral hooks
  • linkedinApproved / linkedinApprovedAt - LinkedIn posts
  • isApproved - Overall episode approval
Approval timestamps are ISO 8601 strings:
{
  "prfApproved": true,
  "prfApprovedAt": "2024-03-15T10:30:00Z"
}

Build docs developers (and LLMs) love