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.
Instalação
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
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.