Skip to main content

Overview

The Draft Queue is where all AI-generated social content lands after the Social Content Pipeline runs. Every piece of content starts as a draft and moves through a review lifecycle before it gets published. Nothing goes live without manual approval. The queue is managed entirely through API endpoints — giving you full control over the review, approval, scheduling, and publishing workflow.

Draft Lifecycle

Every draft moves through a defined set of statuses:
generating --> draft --> reviewed --> approved --> scheduled --> posted
                  \                       \
                   --> rejected             --> failed
StatusDescription
generatingPipeline is actively creating this content (text, images in progress)
draftGeneration complete. Ready for initial review.
reviewedHas been looked at and has review notes, but not yet approved or rejected.
approvedContent is approved and ready to publish or schedule.
scheduledApproved with a specific scheduled_at timestamp for future posting.
postedContent has been published to the target platform.
rejectedContent was rejected during review with a rejection_reason.
failedPipeline encountered an error during generation.

API Endpoints

List Drafts

Retrieve drafts with optional filters for status, platform, content type, and pagination.
GET /api/v1/social/drafts?status=draft&platform=tiktok&limit=50
Query Parameters:
ParameterTypeDefaultDescription
statusstringFilter by lifecycle status
platformstringFilter by platform (tiktok, instagram, x, youtube, linkedin)
contentTypestringFilter by content type (strain-breakdown, myth-bust, etc.)
limitnumber50Max results per page (1-100)
offsetnumber0Pagination offset
Response:
{
  "data": {
    "drafts": [
      {
        "id": "uuid",
        "platform": "instagram",
        "contentType": "strain-breakdown",
        "status": "draft",
        "sourceSlug": "blue-dream",
        "text": "Professor High here with a deep dive into Blue Dream...",
        "hashtags": ["#BlueDream", "#CannabisTerpenes", "#ProfessorHigh"],
        "imageUrls": ["https://..."],
        "metadata": { "slideCount": 5, "characterCount": 2100 },
        "createdAt": "2026-04-11T18:00:00Z",
        "scheduledAt": null,
        "reviewNotes": null
      }
    ],
    "total": 142,
    "limit": 50,
    "offset": 0
  }
}

Get Single Draft

Retrieve the full details of a single draft including all images and metadata.
GET /api/v1/social/drafts/:id

Update Draft Status

Move a draft through the lifecycle. Include optional review notes, rejection reason, or scheduled timestamp.
PATCH /api/v1/social/drafts/:id/status
Request Body:
{
  "status": "approved",
  "review_notes": "Good to go. Minor tweak to hashtags needed.",
  "scheduled_at": "2026-04-14T14:00:00Z"
}
FieldTypeRequiredDescription
statusstringYesTarget status (reviewed, approved, rejected, scheduled, posted)
review_notesstringNoNotes from the reviewer
rejection_reasonstringNoRequired when status is rejected
scheduled_atstring (ISO 8601)NoPublishing timestamp. Sets status to scheduled automatically.

Bulk Approve

Approve multiple drafts at once. Useful after batch review sessions.
POST /api/v1/social/drafts/bulk-approve
Request Body:
{
  "ids": [
    "550e8400-e29b-41d4-a716-446655440000",
    "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
  ]
}

Content Stats

Get aggregate statistics about the draft queue and content generation.
GET /api/v1/social/stats
Response:
{
  "data": {
    "byStatus": {
      "draft": 23,
      "reviewed": 8,
      "approved": 12,
      "scheduled": 35,
      "posted": 142,
      "rejected": 5,
      "failed": 2
    },
    "byPlatform": {
      "instagram": 85,
      "x": 62,
      "tiktok": 41,
      "youtube": 22,
      "linkedin": 17
    },
    "byContentType": {
      "strain-breakdown": 68,
      "science-explainer": 45,
      "myth-bust": 34,
      "carousel": 28,
      "thread": 22,
      "other": 30
    },
    "thisWeek": {
      "generated": 35,
      "approved": 28,
      "posted": 21
    }
  }
}

Database Schema

The social_content_drafts table in Supabase stores all generated content:
ColumnTypeDescription
iduuidPrimary key
platformtextTarget platform (tiktok, instagram, x, youtube, linkedin)
content_typetextContent category (strain-breakdown, myth-bust, etc.)
content_pillartextStrategy pillar (strain-intel, science-drops, myth-busting, lifestyle, app-features, community)
statustextLifecycle status (see lifecycle above)
source_typetextSource data type (strain, blog, terpene, general)
source_slugtextSlug of the source strain, blog post, or terpene
texttextGenerated post text / thread content
hashtagstext[]Array of hashtag strings
image_urlstext[]Array of Supabase Storage URLs for generated images
metadatajsonbPlatform-specific metadata (slide count, character count, thread length, etc.)
ai_model_texttextModel used for text generation (e.g., claude-sonnet)
ai_model_imagetextModel used for image generation (e.g., gemini)
review_notestextReviewer notes
rejection_reasontextReason for rejection (if rejected)
scheduled_attimestamptzPlanned publish time
posted_attimestamptzActual publish time
trigger_run_idtextTrigger.dev run ID for traceability
created_attimestamptzWhen the draft was created
updated_attimestamptzLast modification time

Storage

Generated images are stored in the social-content Supabase Storage bucket:
Path PatternContent
{draft_id}/image_{index}.pngStandard post images
{draft_id}/carousel/slide_{index}.pngInstagram carousel slides
{draft_id}/thumbnail.pngVideo thumbnail concepts

Review Workflow

1

Check the Queue

List new drafts filtered by status draft:
GET /api/v1/social/drafts?status=draft&limit=20
2

Review Each Draft

Open individual drafts to review text, images, and hashtags. Check that the Professor High voice is consistent and the content is accurate.
GET /api/v1/social/drafts/:id
3

Approve, Edit, or Reject

Approve drafts that are ready. Reject those that miss the mark with a reason. Add review notes for context.
PATCH /api/v1/social/drafts/:id/status
{ "status": "approved" }
4

Schedule Approved Content

Set publish timestamps for approved drafts to build out your content calendar:
PATCH /api/v1/social/drafts/:id/status
{ "status": "scheduled", "scheduled_at": "2026-04-14T14:00:00Z" }
5

Publish and Mark as Posted

Copy content to your social media tool or post directly. Then mark the draft as posted:
PATCH /api/v1/social/drafts/:id/status
{ "status": "posted" }
Use the bulk approve endpoint after batch review sessions to approve multiple drafts at once instead of updating them one by one.
Check the stats endpoint regularly to monitor your content pipeline health — how many drafts are waiting, how many are scheduled, and your generation-to-publish ratio.
Rejected drafts are kept in the database for analytics and pipeline improvement. They are not deleted automatically. Review rejection_reason values periodically to identify patterns that may need prompt tuning.