Skip to content

Agent: Lessons

List lessons

GET /api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/

Requires lessons: view.

Authentication: API key — Authorization: Bearer <key>

Parameter In Required Description
chapter_pk path yes
course_pk path yes
COURSE_PK="..."
CHAPTER_PK="..."
curl -sS -X GET "https://www-dev.yoshuko.com/api/v1/agent/courses/$COURSE_PK/chapters/$CHAPTER_PK/lessons/" \
  -H "Authorization: Bearer $YOSHUKO_API_KEY"
import os
import requests

course_pk = "..."
chapter_pk = "..."
url = f"https://www-dev.yoshuko.com/api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/"
response = requests.get(url, headers={"Authorization": f"Bearer {os.environ['YOSHUKO_API_KEY']}"}, timeout=30)
response.raise_for_status()
print(response.json() if response.content else response.status_code)
const course_pk = "...";
const chapter_pk = "...";
const response = await fetch(`https://www-dev.yoshuko.com/api/v1/agent/courses/${course_pk}/chapters/${chapter_pk}/lessons/`, {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.YOSHUKO_API_KEY}` }
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(response.status === 204 ? response.status : await response.json());
Status Meaning
200 No response body
401 Missing, unknown, revoked or expired key; or the organisation's plan is inactive (subscription_inactive) or unverified (org_unverified).
403 The key's scope for this resource does not allow the action.
429 Rate limited (300 requests/hour per key). Retry after the Retry-After header.

Create a lesson

POST /api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/

Requires lessons: edit. content_type selects the lesson kind (quiz, lesson, video, document, assignment, embed); content is validated by the same rules the creator studio uses.

Authentication: API key — Authorization: Bearer <key>

Parameter In Required Description
chapter_pk path yes
course_pk path yes

Request body (JSON):

{
  "title": "string",
  "position": 0,
  "is_published": true,
  "content_type": "quiz",
  "content": null,
  "is_free_preview": true,
  "opens_day_offset": 0,
  "opens_time": "string",
  "closes_day_offset": 0,
  "closes_time": "string",
  "view_window_minutes": 0
}
COURSE_PK="..."
CHAPTER_PK="..."
curl -sS -X POST "https://www-dev.yoshuko.com/api/v1/agent/courses/$COURSE_PK/chapters/$CHAPTER_PK/lessons/" \
  -H "Authorization: Bearer $YOSHUKO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title": "string", "position": 0, "is_published": true, "content_type": "quiz", "content": null, "is_free_preview": true, "opens_day_offset": 0, "opens_time": "string", "closes_day_offset": 0, "closes_time": "string", "view_window_minutes": 0}'
import os
import requests

course_pk = "..."
chapter_pk = "..."
url = f"https://www-dev.yoshuko.com/api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/"
payload = {
  "title": "string",
  "position": 0,
  "is_published": True,
  "content_type": "quiz",
  "content": None,
  "is_free_preview": True,
  "opens_day_offset": 0,
  "opens_time": "string",
  "closes_day_offset": 0,
  "closes_time": "string",
  "view_window_minutes": 0
}
response = requests.post(url, headers={"Authorization": f"Bearer {os.environ['YOSHUKO_API_KEY']}"}, json=payload, timeout=30)
response.raise_for_status()
print(response.json() if response.content else response.status_code)
const course_pk = "...";
const chapter_pk = "...";
const response = await fetch(`https://www-dev.yoshuko.com/api/v1/agent/courses/${course_pk}/chapters/${chapter_pk}/lessons/`, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.YOSHUKO_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "title": "string",
    "position": 0,
    "is_published": true,
    "content_type": "quiz",
    "content": null,
    "is_free_preview": true,
    "opens_day_offset": 0,
    "opens_time": "string",
    "closes_day_offset": 0,
    "closes_time": "string",
    "view_window_minutes": 0
  })
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(response.status === 204 ? response.status : await response.json());
Status Meaning
201 No response body
400 Validation failed; the body names each field.
401 Missing, unknown, revoked or expired key; or the organisation's plan is inactive (subscription_inactive) or unverified (org_unverified).
403 The key's scope for this resource does not allow the action.
429 Rate limited (300 requests/hour per key). Retry after the Retry-After header.

Get a lesson

GET /api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/{id}/

Requires lessons: view.

Authentication: API key — Authorization: Bearer <key>

Parameter In Required Description
chapter_pk path yes
course_pk path yes
id path yes
COURSE_PK="..."
CHAPTER_PK="..."
ID="..."
curl -sS -X GET "https://www-dev.yoshuko.com/api/v1/agent/courses/$COURSE_PK/chapters/$CHAPTER_PK/lessons/$ID/" \
  -H "Authorization: Bearer $YOSHUKO_API_KEY"
import os
import requests

course_pk = "..."
chapter_pk = "..."
id = "..."
url = f"https://www-dev.yoshuko.com/api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/{id}/"
response = requests.get(url, headers={"Authorization": f"Bearer {os.environ['YOSHUKO_API_KEY']}"}, timeout=30)
response.raise_for_status()
print(response.json() if response.content else response.status_code)
const course_pk = "...";
const chapter_pk = "...";
const id = "...";
const response = await fetch(`https://www-dev.yoshuko.com/api/v1/agent/courses/${course_pk}/chapters/${chapter_pk}/lessons/${id}/`, {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.YOSHUKO_API_KEY}` }
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(response.status === 204 ? response.status : await response.json());
Status Meaning
200 No response body
401 Missing, unknown, revoked or expired key; or the organisation's plan is inactive (subscription_inactive) or unverified (org_unverified).
403 The key's scope for this resource does not allow the action.
404 No such object in this key's organisation.
429 Rate limited (300 requests/hour per key). Retry after the Retry-After header.

Update a lesson

PATCH /api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/{id}/

Requires lessons: edit. Optimistic concurrency: send back the updated_at value you last read. If the lesson changed since (a person or another agent edited it), the request is refused with 409 stale_lesson and the current lesson in the body — re-apply your change to that and retry. Nothing is silently overwritten.

Authentication: API key — Authorization: Bearer <key>

Parameter In Required Description
chapter_pk path yes
course_pk path yes
id path yes

Request body (JSON):

{
  "title": "string",
  "position": 0,
  "is_published": true,
  "content_type": "quiz",
  "content": null,
  "is_free_preview": true,
  "opens_day_offset": 0,
  "opens_time": "string",
  "closes_day_offset": 0,
  "closes_time": "string",
  "view_window_minutes": 0
}
COURSE_PK="..."
CHAPTER_PK="..."
ID="..."
curl -sS -X PATCH "https://www-dev.yoshuko.com/api/v1/agent/courses/$COURSE_PK/chapters/$CHAPTER_PK/lessons/$ID/" \
  -H "Authorization: Bearer $YOSHUKO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title": "string", "position": 0, "is_published": true, "content_type": "quiz", "content": null, "is_free_preview": true, "opens_day_offset": 0, "opens_time": "string", "closes_day_offset": 0, "closes_time": "string", "view_window_minutes": 0}'
import os
import requests

course_pk = "..."
chapter_pk = "..."
id = "..."
url = f"https://www-dev.yoshuko.com/api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/{id}/"
payload = {
  "title": "string",
  "position": 0,
  "is_published": True,
  "content_type": "quiz",
  "content": None,
  "is_free_preview": True,
  "opens_day_offset": 0,
  "opens_time": "string",
  "closes_day_offset": 0,
  "closes_time": "string",
  "view_window_minutes": 0
}
response = requests.patch(url, headers={"Authorization": f"Bearer {os.environ['YOSHUKO_API_KEY']}"}, json=payload, timeout=30)
response.raise_for_status()
print(response.json() if response.content else response.status_code)
const course_pk = "...";
const chapter_pk = "...";
const id = "...";
const response = await fetch(`https://www-dev.yoshuko.com/api/v1/agent/courses/${course_pk}/chapters/${chapter_pk}/lessons/${id}/`, {
  method: "PATCH",
  headers: { Authorization: `Bearer ${process.env.YOSHUKO_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "title": "string",
    "position": 0,
    "is_published": true,
    "content_type": "quiz",
    "content": null,
    "is_free_preview": true,
    "opens_day_offset": 0,
    "opens_time": "string",
    "closes_day_offset": 0,
    "closes_time": "string",
    "view_window_minutes": 0
  })
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(response.status === 204 ? response.status : await response.json());
Status Meaning
200 No response body
400 Validation failed, or updated_at was not sent.
401 Missing, unknown, revoked or expired key; or the organisation's plan is inactive (subscription_inactive) or unverified (org_unverified).
403 The key's scope for this resource does not allow the action.
404 No such object in this key's organisation.
409 stale_lesson: changed since you read it; the body carries the current lesson.
429 Rate limited (300 requests/hour per key). Retry after the Retry-After header.

Delete a lesson

DELETE /api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/{id}/

Requires lessons: edit.

Authentication: API key — Authorization: Bearer <key>

Parameter In Required Description
chapter_pk path yes
course_pk path yes
id path yes
COURSE_PK="..."
CHAPTER_PK="..."
ID="..."
curl -sS -X DELETE "https://www-dev.yoshuko.com/api/v1/agent/courses/$COURSE_PK/chapters/$CHAPTER_PK/lessons/$ID/" \
  -H "Authorization: Bearer $YOSHUKO_API_KEY"
import os
import requests

course_pk = "..."
chapter_pk = "..."
id = "..."
url = f"https://www-dev.yoshuko.com/api/v1/agent/courses/{course_pk}/chapters/{chapter_pk}/lessons/{id}/"
response = requests.delete(url, headers={"Authorization": f"Bearer {os.environ['YOSHUKO_API_KEY']}"}, timeout=30)
response.raise_for_status()
print(response.json() if response.content else response.status_code)
const course_pk = "...";
const chapter_pk = "...";
const id = "...";
const response = await fetch(`https://www-dev.yoshuko.com/api/v1/agent/courses/${course_pk}/chapters/${chapter_pk}/lessons/${id}/`, {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.YOSHUKO_API_KEY}` }
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(response.status === 204 ? response.status : await response.json());
Status Meaning
204 No response body
401 Missing, unknown, revoked or expired key; or the organisation's plan is inactive (subscription_inactive) or unverified (org_unverified).
403 The key's scope for this resource does not allow the action.
404 No such object in this key's organisation.
429 Rate limited (300 requests/hour per key). Retry after the Retry-After header.