---
name: creatora
description: Use when building or managing online course platforms, creating courses, managing student access, handling orders and payments, integrating with external systems via GraphQL API, or automating course and student workflows. Reach for this skill when working with course creation, student management, access control, pricing/offers, or API integrations.
metadata:
    mintlify-proj: creatora
    version: "1.0"
---

# Creatora Skill

## Product summary

Creatora is a platform for creating branded online course marketplaces. It manages courses, students, orders, payments, and community features. Agents use Creatora to create and organize courses, manage student access, configure pricing and offers, process orders, and integrate with external systems via GraphQL API.

**Key resources:**
- GraphQL API endpoint: `https://api.creatora.io/graphql`
- Admin Panel: Access via browser after signing in
- JWT authentication: Found in Admin Panel → Platform → API → Developer
- Playground: `https://api.creatora.io/playground` for interactive API exploration
- Primary docs: https://www.help.creatora.io/en/

## When to use

Reach for this skill when:
- Creating, organizing, or publishing courses (modules, lessons, quizzes)
- Managing student accounts and course access
- Configuring pricing, offers, coupons, or custom offers
- Processing orders or managing payments
- Building integrations with external systems (checkout, email marketing, analytics)
- Querying platform data (courses, students, orders, offers)
- Granting or revoking student access to courses
- Troubleshooting course visibility, student access, or API errors

## Quick reference

### API Endpoint and Headers

| Item | Value |
|------|-------|
| Endpoint | `POST https://api.creatora.io/graphql` |
| Auth header | `Authorization: Bearer <JWT>` |
| Access mode | `X-CREATORA-ACCESS-MODE: administrator` |
| Content type | `application/json` |

### Course Statuses

| Status | Visibility | Purchasable | Use case |
|--------|-----------|-------------|----------|
| Private | Admins + students with access only | No | Development, testing |
| Public | All visitors | Yes (if checkout configured) | Live sales |
| Waitlist | All visitors | No | Pre-launch, building interest |
| Archived | Hidden from all | No | Retired courses |

### Core Data Model

| Entity | Purpose | Key fields |
|--------|---------|-----------|
| Platform | Your branded space | id, host, currency |
| Course | Learning content | id, name, status, modules |
| Module | Organized lessons | id, content (lessons/quizzes) |
| Student | Account entity | id, email, role (student/administrator) |
| Offer | What can be purchased | id, price, includes courses/levels/services |
| Order | Sale record | id, status, student, offer, amount |
| Level | Course tier/variant | id, unlocks selected modules |

### Common GraphQL Operations

| Task | Operation | Returns |
|------|-----------|---------|
| Identify current account | `query { me { id } platform { id } }` | Account and platform IDs |
| List courses | `query { courses(limit: 10) { id name status } }` | Course list |
| Get course details | `query { courseById(courseId: "<ID>") { ... } }` | Full course data |
| Create course | `mutation { createCourse(name: "...", defaultOfferPrice: 0.0) { id } }` | New private course |
| Find student by email | `query { students(email: { equals: "..." }) { id email role } }` | Student ID |
| Get student's courses | `query { studentById(studentId: "<ID>") { courses { id } } }` | Student's accessible courses |
| Grant course access | `mutation { grantCourseOwnershipToStudent(courseId: "<ID>", studentId: "<ID>") }` | Unit (no receipt) |
| List orders | `query { orders(pagination: { limit: 10 }) { id status amount } }` | Order list |

### Variable Formats

| Type | Format |
|------|--------|
| UUID | String (e.g., "550e8400-e29b-41d4-a716-446655440000") |
| DateTime | Unix milliseconds as integer |
| Price | Decimal number (e.g., 29.99) |
| Pagination limit | Integer, no guaranteed complete export |

## Decision guidance

### When to use direct access grant vs. order

| Scenario | Use direct grant | Use order |
|----------|-----------------|----------|
| Admin manually assigning course | ✓ | |
| Student purchased via external checkout | | ✓ |
| Subscription system managing access | ✓ | |
| Recording a sale in Creatora | | ✓ |
| Testing or free access | ✓ | |
| Bank transfer or offline payment | | ✓ (manual order) |

**Key difference:** Direct grants leave no commercial history; orders record sales. Choose based on whether you need to track the transaction.

### When to use Creatora checkout vs. external checkout

| Approach | Use when | Trade-offs |
|----------|----------|-----------|
| Creatora checkout | Using Creatora sales pages, want built-in offers/coupons | Limited to Creatora features |
| External checkout + Creatora API | You have custom landing pages, need full control | You manage student/order creation via API |
| External checkout only | You don't need Creatora's sales features | No integration with Creatora data |

### When to use course levels

| Use case | Approach |
|----------|----------|
| Single course tier | No levels needed |
| Multiple tiers (Basic/Pro/Premium) | Create levels, assign modules to each |
| Tiered offers | Create offers that include course + specific level |
| Gating content by tier | Assign modules to levels; students see union of common + level modules |

## Workflow

### Creating and publishing a course

1. **Create the course via API or Admin Panel**
   - API: Call `createCourse(name, defaultOfferPrice)` → returns private course
   - Admin Panel: Products > Courses > Create
   - Course starts as Private; not visible to students

2. **Organize curriculum**
   - Add modules to the course
   - Add lessons (video) or quizzes to each module
   - Check all content is ready (videos uploaded, quizzes complete)

3. **Configure sales page** (if selling)
   - Admin Panel: Products > Course catalog > Sales page
   - Add sales blocks, benefits, FAQ, instructor info
   - Customize purchase card messaging

4. **Set pricing and offers**
   - Base offer created automatically with course
   - Create custom offers if needed (bundles, levels, services)
   - Configure coupons for promotions

5. **Connect payment method** (if using Creatora checkout)
   - Admin Panel: Sales > Checkout > Connect Stripe
   - Use test keys for testing; switch to live keys for production

6. **Change course status to Public**
   - Admin Panel: Products > Courses > General > Status = Public
   - Course now visible and purchasable (if checkout configured)

7. **Test the purchase flow**
   - Complete a test purchase from start to finish
   - Verify student receives access after payment

### Granting a student course access via API

1. **Find the student**
   - Query: `students(email: { equals: "student@example.com" })`
   - Verify returned email and role = "student"
   - Keep the returned `studentId`

2. **Get the course ID**
   - Query: `courses(limit: 10)` or `courseById(courseId: "<ID>")`
   - Keep the `courseId`

3. **Check current access** (optional but recommended)
   - Query: `studentById(studentId: "<ID>") { courses { id } }`
   - Verify course is not already assigned

4. **Grant access**
   - Mutation: `grantCourseOwnershipToStudent(courseId: "<ID>", studentId: "<ID>")`
   - Returns `Unit` (no receipt); check for errors

5. **Verify the grant**
   - Query student's courses again
   - Confirm course now appears in their library

### Integrating external checkout with Creatora

1. **Get your JWT and platform ID**
   - Admin Panel: Platform > API > Developer
   - Copy JWT; keep it private
   - Note your platform ID from `query { platform { id } }`

2. **After external purchase, create student and order**
   - If student doesn't exist, use API to find or create them
   - Create an Order record in Creatora with purchase details
   - Ensure order status reflects payment success

3. **Grant course access**
   - Use `grantCourseOwnershipToStudent` or create an acquisition
   - Student now has access to purchased course

4. **Handle subscription access**
   - On subscription activation: grant course access
   - On subscription renewal: verify access is active
   - On subscription cancellation: revoke access via API

## Common gotchas

- **JWT is a session credential, not an integration key.** Store it outside source code and logs. Signing out of the browser does not revoke it. Treat it as a secret.

- **Missing or wrong access-mode header selects Student mode.** Always send `X-CREATORA-ACCESS-MODE: administrator` explicitly for admin operations. An empty value or typo silently switches to Student mode and can return wrong data or authorization errors.

- **Do not retry mutations blindly.** If `createCourse` or `grantCourseOwnershipToStudent` times out or returns ambiguous results, check the current state (list courses or student's courses) before retrying. A second call can create a duplicate or fail silently.

- **Course names are not unique.** If you cannot identify whether a course was created, investigate in the Admin Panel before retrying. Use the returned ID, not the name.

- **Deleting course content deletes completion data.** Removing lessons or quizzes also removes student progress. Archive or hide content instead if you want to preserve history.

- **Changing course status affects all students.** Moving a course to Archived removes access for all students, even those who purchased it. Use Private or Waitlist if you want to pause sales without removing access.

- **Level grants require parent course access.** If you grant a level without the course, the level is inaccessible. Always grant the course first.

- **Removing course access removes dependent level access.** If a student has access via a level, removing the course also removes the level.

- **Orders and direct grants are different.** An order records a sale; a direct grant does not. Do not use direct grants for checkout callbacks—use orders instead.

- **Pagination does not guarantee complete export.** Records sharing a timestamp can be skipped. Use pagination for bounded reads, not lossless traversal.

- **Check errors even on HTTP 200.** GraphQL can return partial data with an errors array. Always check the `errors` field.

- **Stripe test vs. live keys must match.** Public and Secret keys must be from the same Stripe account and mode (test or live).

## Verification checklist

Before submitting work:

- [ ] JWT is stored securely outside source code and logs
- [ ] All API requests include `Authorization: Bearer <JWT>` and `X-CREATORA-ACCESS-MODE: administrator` headers
- [ ] GraphQL queries use correct variable types (UUID as string, DateTime as Unix milliseconds)
- [ ] Errors are checked in the response even if HTTP status is 200
- [ ] Course creation: verified course exists in Admin Panel before retrying
- [ ] Student access: verified student's courses list after granting access
- [ ] Course status: confirmed course is Public before expecting it to be visible
- [ ] Stripe keys: confirmed test keys are used for testing, live keys for production
- [ ] Pagination: used `limit` to bound reads; did not assume complete export
- [ ] Course deletion: confirmed no student data loss or unintended access revocation
- [ ] Level assignments: confirmed parent course access exists before granting level
- [ ] Order vs. grant: chose the right approach (order for sales, grant for admin actions)

## Resources

**Comprehensive navigation:** https://www.help.creatora.io/llms.txt

**Critical documentation pages:**
- API Reference: https://www.help.creatora.io/en/api/
- API Quickstart: https://www.help.creatora.io/en/api/quickstart
- API Recipes (task-based workflows): https://www.help.creatora.io/en/api/recipes/
- Core Concepts (data model): https://www.help.creatora.io/en/api/core-concepts
- Authentication: https://www.help.creatora.io/en/api/authentication
- GraphQL Playground: https://api.creatora.io/playground

---

> For additional documentation and navigation, see: https://www.help.creatora.io/llms.txt