Upload Course Data
Registers subtitles (script), videos (video), and materials (content) to a course.
Path Parameters
- course_idStringrequired
- Course ID
Request Body (multipart/form-data)
- metadataArray of objectsrequired
- File metadata JSON array
- clip_idString
- Clip ID. Required for script and video types; for content, set it only when the material belongs to a clip.
- section_idString
- Section ID. Set it to register content as a section-level material. Cannot be used together with clip_id.
- typescript | video | contentrequired
- Data type
scriptSubtitle filevideoVideo file or video URLcontentCourse material. Omit both clip_id and section_id to register it at the course level.
- file_nameStringrequired
- File name or video URL
- filesArray of files
- Files to upload. Not needed for video type registered by URL.
Response Fields
- course_idStringrequired
- Course ID
- upload_resultsArray of objectsrequired
- Upload result array
- client_identityString
- Client identifier
- material_idString
- Material unique ID
- section_idString
- Section ID (for section-level materials)
- clip_idString
- Clip ID (for clip-level materials)
- file_nameString
- File name
- sizeNumber
- File size (bytes)
- statusString
- Processing status
- file_log_idString
- File log ID
- descriptionString
- Description or error message
- is_generated_from_videoBoolean
- Whether generated from video URL
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_2", "type": "video", "file_name": "https://example.com/video.mp4"},
{"type": "content", "file_name": "syllabus.pdf"}
]' \
-F 'files=@script.vtt' \
-F 'files=@syllabus.pdf'import json
import requests
res = requests.post(
"https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/materials",
headers={"TAP-API-KEY": "{YOUR_API_KEY}"},
data={"metadata": json.dumps([
{
"clip_id": "1000_1",
"type": "script",
"file_name": "script.vtt"
},
{
"clip_id": "1000_2",
"type": "video",
"file_name": "https://example.com/video.mp4"
},
{
"type": "content",
"file_name": "syllabus.pdf"
}
])},
files=[("files", open("script.vtt", "rb")), ("files", open("syllabus.pdf", "rb"))],
)
print(res.json())package main
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var buf bytes.Buffer
w := multipart.NewWriter(&buf)
w.WriteField("metadata", `[
{"clip_id": "1000_1", "type": "script", "file_name": "script.vtt"},
{"clip_id": "1000_2", "type": "video", "file_name": "https://example.com/video.mp4"},
{"type": "content", "file_name": "syllabus.pdf"}
]`)
f, _ := os.Open("script.vtt")
part, _ := w.CreateFormFile("files", "script.vtt")
io.Copy(part, f)
f.Close()
f2, _ := os.Open("syllabus.pdf")
part2, _ := w.CreateFormFile("files", "syllabus.pdf")
io.Copy(part2, f2)
f2.Close()
w.Close()
req, _ := http.NewRequest("POST", "https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/materials", &buf)
req.Header.Set("TAP-API-KEY", "{YOUR_API_KEY}")
req.Header.Set("Content-Type", w.FormDataContentType())
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
b, _ := io.ReadAll(res.Body)
fmt.Println(string(b))
}import okhttp3.*;
import java.io.File;
public class Main {
public static void main(String[] args) throws Exception {
OkHttpClient client = new OkHttpClient();
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
builder.addFormDataPart("metadata", """
[
{
"clip_id": "1000_1",
"type": "script",
"file_name": "script.vtt"
},
{
"clip_id": "1000_2",
"type": "video",
"file_name": "https://example.com/video.mp4"
},
{
"type": "content",
"file_name": "syllabus.pdf"
}
]
""");
builder.addFormDataPart("files", "script.vtt", RequestBody.create(new File("script.vtt"), MediaType.get("application/octet-stream")));
builder.addFormDataPart("files", "syllabus.pdf", RequestBody.create(new File("syllabus.pdf"), MediaType.get("application/pdf")));
Request.Builder rb = new Request.Builder()
.url("https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/materials")
.header("TAP-API-KEY", "{YOUR_API_KEY}")
.post(builder.build());
try (Response res = client.newCall(rb.build()).execute()) {
System.out.println(res.body().string());
}
}
}import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("metadata", JSON.stringify([
{
"clip_id": "1000_1",
"type": "script",
"file_name": "script.vtt"
},
{
"clip_id": "1000_2",
"type": "video",
"file_name": "https://example.com/video.mp4"
},
{
"type": "content",
"file_name": "syllabus.pdf"
}
]));
form.append("files", new Blob([await readFile("script.vtt")]), "script.vtt");
form.append("files", new Blob([await readFile("syllabus.pdf")]), "syllabus.pdf");
const res = await fetch("https://tap-file-upload-production.coxwave.link/api/v1/courses/1000/materials", {
method: "POST",
headers: {"TAP-API-KEY": "{YOUR_API_KEY}"},
body: form,
});
console.log(await res.json());Response
{
"course_id": "1000",
"upload_results": [
{
"client_identity": "Coxwave",
"material_id": "40d2f656-0ea8-41e0-8ea5-fd90da314178",
"section_id": null,
"clip_id": "1000_1",
"file_name": "script.vtt",
"size": 173,
"status": "UPLOADING",
"file_log_id": "6836cf0f767332a07065455a",
"description": null,
"is_generated_from_video": false
},
{
"client_identity": "Coxwave",
"material_id": "8c1e2a44-5b7d-4c11-9f0e-2a6d3b7c9e10",
"section_id": null,
"clip_id": "1000_2",
"file_name": "https://example.com/video.mp4",
"size": 0,
"status": "UPLOADING",
"file_log_id": "6836cf0f767332a07065455b",
"description": null,
"is_generated_from_video": true
},
{
"client_identity": "Coxwave",
"material_id": "f3a9c0d1-7e42-4b8a-a5c6-1d2e3f4a5b6c",
"section_id": null,
"clip_id": null,
"file_name": "syllabus.pdf",
"size": 48213,
"status": "UPLOADING",
"file_log_id": "6836cf0f767332a07065455c",
"description": null,
"is_generated_from_video": false
}
]
}