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_hereBase URL
https://skillnest.app/api/public/v1Endpoints
/workshopsscope: workshops:readLists 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 }
}
}/workshops/:documentIdscope: workshops:readReturns 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": {}
}/workshopsscope: workshops:writeCreates 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.
/workshops/:documentIdscope: workshops:writeUpdates 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
| Field | Type | Writable | Notes |
|---|---|---|---|
| id | number | No | Numeric Strapi ID. Prefer documentId for lookups — it's stable across draft/publish. |
| documentId | string | No | Stable identifier — this is the :documentId used in endpoint paths. |
| slug | string | No | Auto-generated from title. |
| title | string | Yes | |
| description | string | Yes | Plain text. |
| link | string | Yes | External URL for the workshop, if any. |
| type | enum | Yes | "Short term workshop" | "Project sprint" | "Challenge-based learning" | "Weekly studio" | "Professional studio" | "Learn It!" | "Make It!" |
| audience | enum | Yes | "University students" | "High school students" | "Artisans" | "Unprivileged" | "Other" |
| level | enum | Yes | "Introductory" | "Beginner" | "Intermediate" | "Advanced" |
| participants | integer | Yes | Capacity — max participants. |
| duration | integer | Yes | Duration in hours. |
| objectives | string[] | Yes | Ordered list of learning objectives. |
| prerequisites | string[] | Yes | Ordered list of prerequisites. |
| lab | relation | No | Always set from your API key's lab. Silently ignored if present in a request body. |
| authors, skillgaps, surveys, workshop_sessions | relation | No | Included in responses when populated by the endpoint. Not settable through this API. |
| cover, gallery | media | No | Strapi media objects. Not settable through this API. |
| curriculum, preAssessment, postAssessment | dynamic zone | No | Structured content blocks, only returned by GET /workshops/:documentId. Not settable through this API. |
| seo, documents | component | No | Not settable through this API. |
| createdAt, updatedAt | string (ISO 8601) | No | |
| publishedAt | string (ISO 8601) | null | No | null until the entry is published from the admin panel — workshops created via this API start as drafts. |
Errors
| Status | Meaning |
|---|---|
| 401 | Missing, invalid, revoked, or expired API key. |
| 403 | The key doesn't have the required scope for this request. |
| 404 | The 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.