Use when staff need to create a marketing course from scratch or by cloning another course via API; do NOT use for updating an existing course or editing course translations only.
Installation
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Use when staff need to create a marketing course from scratch or by cloning another course via API; do NOT use for updating an existing course or editing course translations only.
requires
[]
Skill: Create or Clone Marketing Course
When to Use
Use when the goal is to create a new course through POST /v1/marketing/academy/course.
Use for both creation modes: scratch and clone.
Use when staff need to list marketing courses they may manage or clone from (authenticated GET /v1/marketing/academy/course).
Use when the request includes source-course permission or slug-conflict concerns.
Do NOT use for translation-only updates; use translation endpoints after creation.
Do NOT use for updating an existing course.
Concepts
scratch_create: A normal course create where core required fields must be sent explicitly.
clone_create: A create request that includes source_course; non-identity fields are copied from source and can be overridden by payload.
source_course: Source course identifier (slug or numeric id) used only for cloning.
Academy header: Required academy scope for all /academy/ marketing endpoints. For multi-academy staff list, send comma-separated numeric academy IDs (e.g. Academy: 12,34). Slugs are not accepted on that list endpoint.
Cross-academy clone: Destination is the Academy header on POST; source_course may belong to another academy if the caller has crud_course on that source course’s academy (see clone permissions below).
Workflow
Confirm destination academy and send Academy: <academy_id> header.
(Optional clone discovery) List courses the actor may see for clone sourcing: GET /v1/marketing/academy/course with Authorization and Academy: <id> or Academy: <id1,id2,...> (numeric IDs only). Build the id list from GET /v1/auth/user/me (memberships) and GET /v1/auth/me/academy/<slug_or_id>/capabilities (confirm crud_course) if needed. Prefer numeric course id in source_course when the same slug could exist in more than one academy.
Determine mode: if source_course is provided, use clone flow; otherwise use scratch flow.
For scratch flow, collect required fields: slug, icon_url, technologies.
For clone flow, collect slug and source_course; verify caller has crud_course capability in destination academy and source academy.
Permissions:crud_course with read aggregation: academies in the header without the capability are skipped; if none remain, the request fails with 403. When some requested academies are skipped, the JSON body includes academy_scope (requested_academy_ids, applied_academy_ids, resolution: partial). When the caller has access to every requested academy, academy_scope is omitted.
Query: Same list ergonomics as other marketing lists where applicable: optional lang, country_code; pagination uses limit / offset (see staff API index). Optional sort overrides default sort.
Response: Courses owned by the applied academies (Course.academy_id), excluding DELETED. Includes PRIVATE visibility rows (unlike public GET /v1/marketing/course, which is AllowAny and does not validate staff capabilities). Does not include resale-only catalog composition.
Not for: Anonymous catalog browsing — use public GET /v1/marketing/course for that (no capability checks on ?academy=).
Detail path:GET /v1/marketing/academy/course/<course_identifier> returns 405 (use other routes to read a single course in staff context if available).
Source course not found (source-course-not-found): verify source_course slug/id and retry.
Source permission missing (source-course-forbidden): use a source academy where caller has crud_course, or change actor token.
Slug conflict on create: send a different slug; no automatic suffixing is applied.
Invalid cohort on create/clone: if cohort is not never-ending, not SaaS-available, or not in destination academy, provide a valid cohort or omit it.
Translation data expected on create: create course first, then call translation update endpoints.
Public catalog vs staff list: GET /v1/marketing/course?academy=... does not prove clone permission; use staff list above for permission-scoped discovery before clone.
Data Model Clarification
Course.syllabus is many-to-many because a marketing course can bundle or present multiple syllabi.
Admissions runtime entities (for example schedule/version objects) use syllabus foreign keys because each runtime object must point to one concrete syllabus/version at a time.
This is intentional separation: marketing catalog composition vs admissions operational delivery.
Checklist
Confirmed mode (scratch_create or clone_create) and destination Academy header.
If clone sourcing across academies, used staff GET /v1/marketing/academy/course (numeric Academy ids) or otherwise confirmed source_course and permissions.
Confirmed required fields for chosen mode (slug + scratch fields or slug + source_course).
For clone mode, confirmed crud_course permission in both source and destination academies.
Confirmed requested slug is final (no auto-rename on conflict).
Submitted POST /v1/marketing/academy/course and validated success payload.
If translations are needed, scheduled translation update endpoints after create.