---
title: "Create Content"
method: POST
path: "/v2/contents"
tags: ["v2 - Contents"]
---

# Create Content

`POST /v2/contents`

## Request

- Base URL: `https://api.jubjubapp.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.jubjubapp.com/v2/contents`
- Auth: HTTP bearer

Create a new content. With an Idempotency-Key (the MCP client sends one
with contents_create), a retry with the same key answers with the piece the
first call made: no second piece, no second reviewer notice (Tom,
2026-10-18; infrastructure/persistence/content_create_keys.py). The key is
claimed only after the caller is seen to be allowed to create here.

ONE FILE, ONE PIECE (2026-10-26). A create that sends no key is claimed
under its video instead (_video_create_key), and _create_content answers
with the piece already on that file. One MP4 in ws_c35a1f5ccba0 became
two pieces: the dashboard filed the finished upload from two places (the
page hook and GlobalUploadProvider), and both creates went through.

## Headers

- `Idempotency-Key` string, nullable
- `Authorization` string
- `X-JubJub-Service-Key` string
- `X-JubJub-Agent-Key` string
- `X-JubJub-Platform-Key` string
- `Origin` string
- `Referer` string
- `X-JubJub-Trial-Token` string

## Request body

- CreateContentRequest: Request to create a new content.
  - `workspace_id` string, required: Workspace that owns this content
  - `title` string, required
  - `description` string, nullable
  - `tags` string[], nullable
  - `video_id` string, required: Reference to uploaded Media (video)
  - `thumbnail_id` string, nullable: Reference to Media (thumbnail)
  - `subtitle_ids` string[], nullable: References to subtitle Media
  - `language` string, nullable: Primary language code (ISO 639-1)
  - `is_made_for_kids` boolean
  - `folder_id` string, nullable
  - `created_by` string, nullable: Profile ID of creator

## Response `201`

Successful Response

- ContentResponse: Full content response.
  - `content_id` string, required
  - `workspace_id` string, nullable
  - `folder_id` string, nullable, required
  - `title` string, required
  - `description` string, nullable, required
  - `tags` string[], nullable, required
  - `video_id` string, required
  - `thumbnail_id` string, nullable, required
  - `thumbnail_url` string, nullable
  - `subtitle_ids` string[], nullable, required
  - `current_version` integer
  - `version_count` integer
  - `approval_status` string
  - `language` string, nullable, required
  - `is_made_for_kids` boolean, required
  - `status` string, required
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, nullable, required
  - `created_by` string, nullable, required
  - `created_by_you` boolean
  - `creator` PublicPerson: A person by public profile. Never an ID, never an email.
    - `member_ref` string, nullable
    - `display_name` string, required
    - `avatar_url` string, nullable
    - `handle` string, nullable
    - `is_you` boolean
    - `role` string, nullable
    - `via_team` string, nullable
  - `ownership_contract_address` string, nullable
  - `token_id` string, nullable
  - `on_chain_tx_hash` string, nullable
  - `on_chain_confirmed` boolean
  - `ownership_status` string
  - `ownership_step` string, nullable
  - `ownership_reason` string, nullable
  - `media_kind` string, nullable
  - `catalogue_contract_address` string, nullable
  - `discoverable` boolean
  - `provenance_tier` string, nullable
  - `provenance_score` integer, nullable
  - `transcript_available` boolean
  - `content_type` string, nullable
  - `topics` string[], nullable
  - `sentiment` string, nullable
  - `production_tier` string, nullable
  - `setting` string, nullable
  - `duration_seconds` number, nullable
  - `questions_answered` string[], nullable
  - `training_caption` string, nullable
  - `cinematographic` object, nullable
  - `provenance_signals` object, nullable
  - `entities_people` string[], nullable
  - `entities_brands` string[], nullable
  - `entities_locations` string[], nullable
  - `chapter_markers` object[], nullable
  - `target_audience` object, nullable
  - `expertise_level` string, nullable
  - `transcript_full` string, nullable
  - `payment_verified` boolean
  - `is_owner` boolean
  - `source` string, nullable
  - `published_at` string, nullable
  - `registered_at` string, nullable
  - `platform` string, nullable
  - `platforms` string[], nullable: List of configured platforms (populated separately)

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/jubjubapp/apis/jubjub-api.md) - [All operations](https://skmtc.dev/jubjubapp/apis/jubjub-api/llms.txt) - [OpenAPI document](https://skmtc.dev/jubjubapp/apis/jubjub-api/revisions/353157b296f2?raw)
