API Reference
Course data upload and management REST API
REST API for uploading and managing course information and data (subtitles, learning materials, etc.).
Common
Base URL
https://tap-file-upload-production.coxwave.linkAuthentication
All API requests require the TAP-API-KEY header.
Request Headers
| Parameter | Type | Required | Description |
|---|---|---|---|
| TAP-API-KEY | String | O | Your issued API key |
Data Types
| Type | Description | Format |
|---|---|---|
| information | Course metadata | JSON |
| script | Lecture subtitle file | SRT, VTT |
| video | Video URL for subtitle extraction | MP4, AVI, MOV, MKV, WMV, FLV, WEBM, M4V, 3GP, OGV |
| content | Learning material documents | PDF, HTML, PY, IPYNB, TXT |
Course Information
Register and manage course metadata (title, description, curriculum, etc.).
Course information is required for the AI tutor to understand the learning context.
List Courses
Request
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| page | Number | - | Page number (default: 1) |
| size | Number | - | Items per page (default: 10) |
Request Example
curl -X GET "https://tap-file-upload-production.coxwave.link/api/v1/courses?page=1&size=10" \
-H "TAP-API-KEY: {YOUR_API_KEY}"Response
| Parameter | Type | Required | Description |
|---|---|---|---|
| pagination | Object | O | Pagination info. See pagination |
| courses | Array of objects | O | Course summary array. See courses item |
pagination
| Field | Type | Description |
|---|---|---|
| current_page | Number | Current page |
| page_size | Number | Items per page |
| total_count | Number | Total items |
| total_pages | Number | Total pages |
| has_next | Boolean | Has next page |
| has_previous | Boolean | Has previous page |
courses item
| Field | Type | Description |
|---|---|---|
| course_id | String | Course ID |
| course_title | String | Course title |
| course_category | String | Course category |
| clip_count | Number | Number of clips |
| total_play_time | Number | Total play time (seconds) |
| upload_date | String | Upload date (YYYY.MM.DD) |
| script_count | Number | Number of subtitles |
| content_count | Number | Number of materials |
| has_sections | Boolean | Has sections |
Response Example
{
"pagination": {
"current_page": 1,
"page_size": 10,
"total_count": 60,
"total_pages": 6,
"has_next": true,
"has_previous": false
},
"courses": [
{
"course_id": "1000",
"course_title": "Python Basics Programming",
"course_category": "Programming",
"clip_count": 4,
"total_play_time": 1800,
"upload_date": "2025.01.15",
"script_count": 3,
"content_count": 8,
"has_sections": true
}
]
}Get Course Information
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_id | String | O | Course ID |
Request Example
curl -X GET "https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/information" \
-H "TAP-API-KEY: {YOUR_API_KEY}"Response
Response Fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_information | Object | O | Course info object. See course_information |
course_information
| Parameter | Type | Required | Description |
|---|---|---|---|
| material_id | String | O | Material ID |
| client_identity | String | O | Client name |
| course_id | String | O | Course ID |
| course_type | String | - | Course type |
| course_title | String | O | Course title |
| course_description | String | - | Course description |
| course_categories | Array of objects | - | Category list |
| total_play_time | Number | O | Total play time (seconds) |
| total_clip_count | Number | O | Total clip count |
| instructors | Array of objects | - | Instructor list |
| course_curriculum | Object | O | Curriculum |
| created_at | String | O | Created date |
| updated_at | String | - | Updated date |
Response Example
{
"course_information": {
"material_id": "mat_123",
"client_identity": "Coxwave",
"course_id": "1000",
"course_type": "internet",
"course_title": "Python Basics Programming",
"course_description": "A course to learn the basics of Python programming.",
"course_categories": [
{
"site": "coxwave",
"course_category_id": "1",
"course_category_parent_id": "",
"depth": 0,
"course_category_title": "Programming"
}
],
"total_play_time": 1800,
"total_clip_count": 4,
"instructors": [
{ "instructor": "Cox", "instructor_number": "001" }
],
"course_curriculum": {
"sections": [
{
"section_id": "1000_1",
"section_order": 1,
"section_title": "Part 1. Python Basics",
"depth": 1,
"total_play_time": 900,
"total_clip_count": 2,
"clips": [
{
"clip_id": "1000_1_1",
"clip_order": 1,
"clip_title": "Variable Declaration",
"clip_play_time": 450
}
]
}
]
},
"created_at": "2025-01-15T10:00:00",
"updated_at": null
}
}Get Clip Status
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_id | String | O | Course ID |
| clip_id | String | O | Clip ID |
Request Example
curl -X GET "https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/clips/1000_1_1_1/status" \
-H "TAP-API-KEY: {YOUR_API_KEY}"Response
Response Fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| clip_id | String | O | Clip ID |
| status | String | O | Processing status (PENDING, PROCESSING, READY) |
| status_description | String | O | Status description message |
Response Example
{
"clip_id": "1000_1_1_1",
"status": "READY",
"status_description": "Clip is ready to use"
}Register Course Information
Request
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| courses | Array of objects | O | Course info array. See courses item |
courses item
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_id | String | O | Course unique identifier |
| course_type | String | - | Course type (e.g., internet) |
| course_title | String | O | Course title |
| course_description | String | - | Course description |
| total_play_time | Number | O | Total course time (seconds) |
| total_clip_count | Number | O | Total clip count |
| course_categories | Array of objects | - | Category info array |
| instructors | Array of objects | - | Instructor info array |
| course_curriculum | Object | O | Curriculum (sections or clips) |
Category Object
| Parameter | Type | Required | Description |
|---|---|---|---|
| site | String | O | Site name |
| course_category_id | String | O | Category ID |
| course_category_parent_id | String | - | Parent category ID |
| depth | Number | O | Category depth (starts from 0) |
| course_category_title | String | O | Category name |
Instructor Object
| Parameter | Type | Required | Description |
|---|---|---|---|
| instructor | String | O | Instructor name |
| instructor_number | String | - | Instructor number |
Section Object
| Parameter | Type | Required | Description |
|---|---|---|---|
| section_id | String | O | Section unique identifier |
| section_order | Number | O | Section order |
| section_title | String | O | Section title |
| section_description | String | - | Section description |
| depth | Number | O | Section depth (starts from 1) |
| total_play_time | Number | O | Total play time (seconds) |
| total_clip_count | Number | O | Total clip count |
| sections | Array of objects | - | Sub-sections (nestable) |
| clips | Array of objects | - | Clip array |
Clip Object
| Parameter | Type | Required | Description |
|---|---|---|---|
| clip_id | String | O | Clip unique identifier |
| clip_order | Number | O | Clip order |
| clip_title | String | O | Clip title |
| clip_description | String | - | Clip description |
| clip_play_time | Number | O | Play time (seconds) |
| clip_level | Number | - | Difficulty (1: Easy, 2: Normal, 3: Hard) |
A Section can only have either clips or sections, not both.
Request Example
curl -X POST "https://tap-file-upload-production.coxwave.link/api/v1/courses/information" \
-H "Content-Type: application/json" \
-H "TAP-API-KEY: {YOUR_API_KEY}" \
-d '{
"courses": [
{
"course_id": "1000",
"course_type": "internet",
"course_title": "Python Basics",
"course_description": "Basic Python programming course",
"total_play_time": 1800,
"total_clip_count": 4,
"instructors": [{ "instructor": "Cox", "instructor_number": "001" }],
"course_categories": [
{
"site": "coxwave",
"course_category_id": "1",
"course_category_parent_id": "",
"depth": 0,
"course_category_title": "Programming"
}
],
"course_curriculum": {
"sections": [
{
"section_id": "1000_1",
"section_order": 1,
"section_title": "Part 1. Python Basics",
"section_description": "Learn basic Python syntax and data types",
"depth": 1,
"total_play_time": 900,
"total_clip_count": 2,
"clips": [
{
"clip_id": "1000_1_1",
"clip_order": 1,
"clip_title": "Variable Declaration",
"clip_description": "How to declare variables in Python",
"clip_play_time": 450
},
{
"clip_id": "1000_1_2",
"clip_order": 2,
"clip_title": "Data Types Introduction",
"clip_description": "Basic data types (int, str, list, dict)",
"clip_play_time": 450
}
]
},
{
"section_id": "1000_2",
"section_order": 2,
"section_title": "Part 2. Control Statements",
"section_description": "Learn conditionals and loops",
"depth": 1,
"total_play_time": 900,
"total_clip_count": 2,
"clips": [
{
"clip_id": "1000_2_1",
"clip_order": 1,
"clip_title": "Conditionals",
"clip_description": "Using if, elif, else",
"clip_play_time": 450
},
{
"clip_id": "1000_2_2",
"clip_order": 2,
"clip_title": "Loops",
"clip_description": "Using for, while",
"clip_play_time": 450
}
]
}
]
}
}
]
}'Response
Response Fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| success_courses | Array of strings | O | Successfully uploaded course IDs |
| failed_courses | Array of strings | O | Failed course IDs |
Response Example
{
"success_courses": ["1000"],
"failed_courses": []
}Delete Course Information
Warning: When course information is deleted, all data and features associated with that course will no longer be supported.
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_id | String | O | Course ID to delete |
Request Example
curl -X DELETE "https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/information" \
-H "TAP-API-KEY: {YOUR_API_KEY}"Response
Response Fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| message | String | O | Server message |
Response Example
{
"message": "Course information deleted successfully"
}Course Data
Upload and manage subtitles, learning materials, videos for courses.
Uploaded data is used to improve AI tutor answer quality.
Course Subtitles
Subtitle data extracted from lecture videos. Subtitles are the core learning data for the AI tutor.
If subtitles are available
| Category | Format |
|---|---|
| Script | SRT, VTT |
If subtitles are not available
If the original subtitle file is not available, provide the media file download link (URL) in the following formats, and Coxwave will extract subtitles for you.
| Category | Format |
|---|---|
| Video | MP4, AVI, MOV, MKV, WMV, FLV, WEBM, M4V, 3GP, OGV |
Course Materials
Learning materials provided to course students. Not required for AI tutor integration, but recommended for improved answer quality.
| Category | Format |
|---|---|
| Content | PDF, HTML, PY, IPYNB, TXT |
Get Course Data
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_id | String | O | Course ID |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| clip_id | String | - | Filter by specific clip |
Request Example
curl -X GET "https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/materials" \
-H "TAP-API-KEY: {YOUR_API_KEY}"Response
Response Fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_id | String | O | Course ID |
| course_title | String | O | Course title |
| materials | Array of objects | O | Uploaded materials list. See materials item |
materials item
| Field | Type | Description |
|---|---|---|
| client_identity | String | Client name |
| material_id | String | Material unique ID |
| section_id | String | Section ID |
| clip_id | String | Clip ID |
| type | String | Data type |
| file_name | String | File name |
| size | Number | File size (bytes) |
| url | String | File URL |
| status | String | Processing status |
| summary | String | Content summary |
| description | String | Content description |
| is_generated_from_video | Boolean | Whether generated from video URL |
Response Example
{
"course_id": "1000",
"course_title": "Python Basics Programming",
"materials": [
{
"client_identity": "Coxwave",
"material_id": "mat_123",
"section_id": null,
"clip_id": "1000_1",
"type": "script",
"file_name": "lecture1.srt",
"size": 12345,
"url": null,
"status": "EMBEDDED",
"summary": "Lecture content about Python variable declaration",
"description": "Explains how to declare variables in Python basics.",
"is_generated_from_video": false
}
]
}Upload Course Data
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_id | String | O | Course ID |
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| metadata | Array of objects | O | File metadata JSON array. See metadata item |
| files | Array of files | - | Files to upload (except video type) |
metadata item
| Parameter | Type | Required | Description |
|---|---|---|---|
| clip_id | String | - | Clip ID (either clip_id or section_id required) |
| section_id | String | - | Section ID (for section-level material upload) |
| type | String | O | Data type (script, video, content) |
| file_name | String | O | File name or video URL |
Upload target specification: Either clip_id or section_id must be specified. If neither is specified, uploads to course level.
Video type: When type: "video", don't upload the file directly - specify the video download URL in file_name. The server will download the video from that URL and automatically extract subtitles.
Request Example
curl -X POST "https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/materials" \
-H "TAP-API-KEY: {YOUR_API_KEY}" \
-F 'metadata=[
{"clip_id": "1000_1", "type": "script", "file_name": "script.vtt"},
{"clip_id": "1000_1", "type": "content", "file_name": "slides.pdf"},
{"clip_id": "1000_2", "type": "video", "file_name": "https://example.com/video.mp4"}
]' \
-F 'files=@script.vtt' \
-F 'files=@slides.pdf'Response
Response Fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_id | String | O | Course ID |
| upload_results | Array of objects | O | Upload result array. See upload_results item |
upload_results item
| Field | Type | Description |
|---|---|---|
| client_identity | String | Client identifier |
| material_id | String | Material unique ID |
| section_id | String | Section ID (for section-level materials) |
| clip_id | String | Clip ID (for clip-level materials) |
| file_name | String | File name |
| size | Number | File size (bytes) |
| status | String | Processing status |
| file_log_id | String | File log ID |
| is_generated_from_video | Boolean | Whether generated from video URL |
Response Example
{
"course_id": "1000",
"upload_results": [
{
"client_identity": "Coxwave",
"material_id": "40d2f656-0ea8-41e0-8ea5-fd90da314178",
"clip_id": "1000_1",
"file_name": "script.vtt",
"size": 173,
"status": "UPLOADING",
"file_log_id": "6836cf0f767332a07065455a"
}
]
}Delete Course Data
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| course_id | String | O | Course ID |
| material_id | String | O | Material ID to delete |
Request Example
curl -X DELETE "https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/materials/mat_123" \
-H "TAP-API-KEY: {YOUR_API_KEY}"Response
Response Fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| message | String | O | Server message |
Response Example
{
"message": "Material deleted successfully"
}Data Processing Status
Uploaded course data goes through preprocessing, and you can check progress via the status field in the query API.
| Status | Description |
|---|---|
| UPLOADING | File upload in progress |
| UPLOADED | Upload complete |
| UPLOAD_FAILED | Upload failed |
| SUMMARIZING | Content summarization in progress |
| SUMMARIZED | Summarization complete |
| SUMMARIZE_FAILED | Summarization failed |
| EMBEDDING | Vector embedding in progress |
| EMBEDDED | Embedding complete |
| EMBED_FAILED | Embedding failed |
| QUIZ_GENERATING | Quiz generation in progress |
| QUIZ_GENERATED | Quiz generation complete |
| QUIZ_GENERATE_FAILED | Quiz generation failed |
| PING_MESSAGE_GENERATING | Suggested question generation in progress |
| PING_MESSAGE_GENERATED | Suggested question generation complete (all features available) |
| PING_MESSAGE_GENERATE_FAILED | Suggested question generation failed |
Errors
Error Response Format
All errors are returned in the following format:
{
"error_code": "COURSE_NOT_FOUND",
"message": "Course does not exist.",
"status_code": 404
}Error Codes
| HTTP | Error Code | Description | Solution |
|---|---|---|---|
| 400 | INVALID_COURSE_DATA | Invalid course data | Check request data format |
| 400 | EMPTY_CONTENT | Empty content | Check required fields |
| 401 | - | Authentication failed | Check API key |
| 404 | COURSE_NOT_FOUND | Course not found | Check course_id |
| 404 | SECTION_NOT_FOUND | Section not found | Check section_id |
| 404 | CLIP_NOT_FOUND | Clip not found | Check clip_id |
| 404 | MATERIAL_NOT_FOUND | Material not found | Check material_id |
| 409 | DUPLICATE_KEY | Duplicate key | Resource already exists |
| 500 | DATABASE_ERROR | Database error | Contact support |
| 500 | SERVER_ERROR | Internal server error | Contact support |
