API Documentation

Read and sync your lab's workshops from your own website or systems using a personal API key.

Getting an API key

API keys are self-service for lab admins. Go to your admin dashboard API Access, and generate a key. You choose whether it can only read your lab's workshops, or also create and update them. The full key is shown once, right after creation — store it somewhere safe, since skillNest never stores it in plaintext and can't show it to you again.

A key is always scoped to the lab of the admin who created it — it can never read or write another lab's data.

Authentication

Send your key as a bearer token on every request. Keep it on your own server — never in client-side JavaScript, since anyone who can view your page's source could read the key too.

Authorization: Bearer sk_live_your_key_here

Base URL

https://skillnest.app/api/public/v1

Endpoints

GET/workshopsscope: workshops:read

Lists your lab's workshops, newest first. Supports page and pageSize query parameters (default page 1, pageSize 25). Includes both draft and published workshops.

curl https://skillnest.app/api/public/v1/workshops \
  -H "Authorization: Bearer sk_live_your_key_here"
Example response
{
  "data": [
    {
      "id": 482,
      "documentId": "k3f8sxq2m9wz1e4a0p7be91",
      "title": "Intro to Laser Cutting",
      "slug": "intro-to-laser-cutting",
      "description": "A hands-on introduction to laser cutting safety and workflow.",
      "link": null,
      "type": "Short term workshop",
      "audience": "High school students",
      "level": "Beginner",
      "participants": 20,
      "duration": 3,
      "objectives": ["Understand laser safety basics", "Design and cut a simple project"],
      "prerequisites": [],
      "authors": [{ "documentId": "a91q3m...", "name": "Jane Doe" }],
      "skillgaps": [{ "title": "Manufacturing basics" }],
      "cover": { "url": "https://.../cover.jpg" },
      "createdAt": "2026-08-27T20:14:03.221Z",
      "updatedAt": "2026-08-27T20:14:03.221Z",
      "publishedAt": null
    }
  ],
  "meta": {
    "pagination": { "page": 1, "pageSize": 25, "pageCount": 1, "total": 1 }
  }
}
GET/workshops/:documentIdscope: workshops:read

Returns a single workshop, including curriculum and documents. A documentId belonging to another lab returns 404 — see the field reference below.

curl https://skillnest.app/api/public/v1/workshops/abc123 \
  -H "Authorization: Bearer sk_live_your_key_here"
Example response
{
  "data": {
    "id": 482,
    "documentId": "k3f8sxq2m9wz1e4a0p7be91",
    "title": "Intro to Laser Cutting",
    "slug": "intro-to-laser-cutting",
    "description": "A hands-on introduction to laser cutting safety and workflow.",
    "link": null,
    "type": "Short term workshop",
    "audience": "High school students",
    "level": "Beginner",
    "participants": 20,
    "duration": 3,
    "objectives": ["Understand laser safety basics", "Design and cut a simple project"],
    "prerequisites": [],
    "authors": [{ "documentId": "a91q3m...", "name": "Jane Doe" }],
    "skillgaps": [{ "title": "Manufacturing basics" }],
    "cover": { "url": "https://.../cover.jpg" },
    "gallery": [{ "url": "https://.../photo-1.jpg" }],
    "documents": [
      { "id": 12, "name": "Workshop Slides", "type": "Workshop Guide", "visible": "Public", "files": [{ "url": "https://.../slides.pdf" }] }
    ],
    "curriculum": [
      { "__component": "workshop.module", "title": "Safety briefing", "duration": 30 }
    ],
    "lab": { "documentId": "l7d2fz..." },
    "createdAt": "2026-08-27T20:14:03.221Z",
    "updatedAt": "2026-08-27T20:14:03.221Z",
    "publishedAt": null
  },
  "meta": {}
}
POST/workshopsscope: workshops:write

Creates a new draft workshop in your lab. The lab field is set automatically from your key and can't be overridden. Any field from the field reference marked writable can be included — everything is optional except title.

curl -X POST https://skillnest.app/api/public/v1/workshops \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"title": "Intro to Laser Cutting", "level": "Beginner"}'
Full request body example
{
  "title": "Intro to Laser Cutting",
  "description": "A hands-on introduction to laser cutting safety and workflow.",
  "type": "Short term workshop",
  "audience": "High school students",
  "level": "Beginner",
  "participants": 20,
  "duration": 3,
  "objectives": ["Understand laser safety basics", "Design and cut a simple project"],
  "prerequisites": []
}

Responds 201 with the created workshop, in the same shape as GET /workshops/:documentId. It starts as a draft (publishedAt: null) until published from the admin panel.

PUT/workshops/:documentIdscope: workshops:write

Updates a workshop that belongs to your lab. A documentId belonging to another lab returns 404. Only send the fields you want to change — anything omitted is left as-is, and lab is dropped if present.

curl -X PUT https://skillnest.app/api/public/v1/workshops/abc123 \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"title": "Intro to Laser Cutting (updated)"}'
Full request body example
{
  "title": "Intro to Laser Cutting (updated)",
  "participants": 25,
  "duration": 4
}

Responds 200 with the updated workshop, in the same shape as GET /workshops/:documentId.

The Workshop object

Every endpoint above reads and writes this shape. Fields marked not writable are either read-only or simply not part of what this API accepts today — they can still show up in responses when the endpoint populates them.

Full field reference
FieldTypeWritableNotes
idnumberNoNumeric Strapi ID. Prefer documentId for lookups — it's stable across draft/publish.
documentIdstringNoStable identifier — this is the :documentId used in endpoint paths.
slugstringNoAuto-generated from title.
titlestringYes
descriptionstringYesPlain text.
linkstringYesExternal URL for the workshop, if any.
typeenumYes"Short term workshop" | "Project sprint" | "Challenge-based learning" | "Weekly studio" | "Professional studio" | "Learn It!" | "Make It!"
audienceenumYes"University students" | "High school students" | "Artisans" | "Unprivileged" | "Other"
levelenumYes"Introductory" | "Beginner" | "Intermediate" | "Advanced"
participantsintegerYesCapacity — max participants.
durationintegerYesDuration in hours.
objectivesstring[]YesOrdered list of learning objectives.
prerequisitesstring[]YesOrdered list of prerequisites.
labrelationNoAlways set from your API key's lab. Silently ignored if present in a request body.
authors, skillgaps, surveys, workshop_sessionsrelationNoIncluded in responses when populated by the endpoint. Not settable through this API.
cover, gallerymediaNoStrapi media objects. Not settable through this API.
curriculum, preAssessment, postAssessmentdynamic zoneNoStructured content blocks, only returned by GET /workshops/:documentId. Not settable through this API.
seo, documentscomponentNoNot settable through this API.
createdAt, updatedAtstring (ISO 8601)No
publishedAtstring (ISO 8601) | nullNonull until the entry is published from the admin panel — workshops created via this API start as drafts.

Errors

StatusMeaning
401Missing, invalid, revoked, or expired API key.
403The key doesn't have the required scope for this request.
404The workshop doesn't exist, or belongs to a different lab.

Revoking a key

Lost a key, or retiring an integration? Revoke it any time from API Access in your admin dashboard — it stops working immediately and can't be un-revoked.