SkillsLib.ai
REST API v1

API Documentation

Programmatically manage your skills, promotions, and announcements. Build integrations, automate publishing workflows, or sync your catalog with external tools.

Authentication

All API requests must include a valid API key in the Authorization header using the Bearer scheme.

Example Header
Authorization: Bearer sk_live_abc123...

How to get a key

Go to Settings → API Keys and click Create Key. Give it a name and choose an expiry period.

Expiry options

Keys can be set to expire after 30 days, 3 months, 6 months, or 1 year. Expired keys automatically stop working.

Security notes

  • API keys are hashed before storage. The full key is shown only once at creation time.
  • Keys can be revoked at any time from the settings page.
  • Never share your API key or commit it to version control.
  • If you suspect a key has been compromised, revoke it immediately and create a new one.

Endpoints

All endpoints are relative to https://skillslib.ai. Requests and responses use JSON unless otherwise noted.

Skills

GET/api/v1/ext/skills

List your skills. Supports pagination and filtering by publish status.

Response
{
  "skills": [
    {
      "id": "clx...",
      "title": "Contract Analyzer",
      "price": 12.99,
      "published": true,
      "createdAt": "2026-07-01T00:00:00Z"
    }
  ],
  "total": 42,
  "page": 1,
  "limit": 20
}
POST/api/v1/ext/skills

Create a new skill listing. Categories are automatically assigned by AI based on the title, description, and content.

Request Body
{
  "title": "Contract Analyzer",
  "description": "Analyze legal contracts...",
  "price": 12.99,
  "features": ["Clause extraction", "Risk scoring"],
  "tags": ["legal", "contracts"],
  "skillContent": "# System prompt\n..."
}
Response
{
  "id": "clx...",
  "title": "Contract Analyzer",
  "price": 12.99,
  "published": false,
  "createdAt": "2026-07-22T00:00:00Z"
}
GET/api/v1/ext/skills/:id

Get full details for a single skill you own.

Response
{
  "id": "clx...",
  "title": "Contract Analyzer",
  "description": "Analyze legal contracts...",
  "price": 12.99,
  "published": true,
  "features": ["Clause extraction", "Risk scoring"],
  "tags": ["legal", "contracts"],
  "createdAt": "2026-07-01T00:00:00Z",
  "updatedAt": "2026-07-20T00:00:00Z"
}
PUT/api/v1/ext/skills/:id

Update an existing skill. Send only the fields you want to change.

Request Body
{
  "price": 14.99,
  "tags": ["legal", "contracts", "ai"]
}
Response
{
  "id": "clx...",
  "title": "Contract Analyzer",
  "price": 14.99,
  "updatedAt": "2026-07-22T00:00:00Z"
}
DELETE/api/v1/ext/skills/:id

Soft-delete a skill. It will no longer appear in search results or your public store.

Response
{
  "id": "clx...",
  "deleted": true
}
POST/api/v1/ext/skills/:id/upload

Upload or replace the SKILL.md content for a skill. Send as multipart/form-data with a file field.

Request Body
Content-Type: multipart/form-data

file: SKILL.md
Response
{
  "id": "clx...",
  "skillContentUpdatedAt": "2026-07-22T00:00:00Z"
}

Announcements

POST/api/v1/ext/skills/:id/announcements

Create an announcement for a skill. Visible to all buyers.

Request Body
{
  "title": "Version 2.0 Released",
  "body": "Major update with new clause detection..."
}
Response
{
  "id": "clx...",
  "title": "Version 2.0 Released",
  "createdAt": "2026-07-22T00:00:00Z"
}
PUT/api/v1/ext/skills/:id/announcements/:announcementId

Update an existing announcement.

Request Body
{
  "title": "Version 2.0.1 Released",
  "body": "Hotfix for edge case in clause detection..."
}
Response
{
  "id": "clx...",
  "title": "Version 2.0.1 Released",
  "updatedAt": "2026-07-22T00:00:00Z"
}
DELETE/api/v1/ext/skills/:id/announcements/:announcementId

Delete an announcement.

Response
{
  "id": "clx...",
  "deleted": true
}

Promotions

POST/api/v1/ext/skills/:id/promotions

Create a time-limited discount promotion for a skill.

Request Body
{
  "discountPercent": 25,
  "startsAt": "2026-08-01T00:00:00Z",
  "expiresAt": "2026-08-15T23:59:59Z",
  "title": "Summer Sale"
}
Response
{
  "id": "clx...",
  "discountPercent": 25,
  "startsAt": "2026-08-01T00:00:00Z",
  "expiresAt": "2026-08-15T23:59:59Z",
  "title": "Summer Sale"
}
PUT/api/v1/ext/skills/:id/promotions/:promotionId

Update a promotion (e.g. extend the end date or change the discount).

Request Body
{
  "discountPercent": 30,
  "expiresAt": "2026-08-31T23:59:59Z"
}
Response
{
  "id": "clx...",
  "discountPercent": 30,
  "expiresAt": "2026-08-31T23:59:59Z",
  "updatedAt": "2026-07-22T00:00:00Z"
}
DELETE/api/v1/ext/skills/:id/promotions/:promotionId

Cancel an active promotion immediately.

Response
{
  "id": "clx...",
  "cancelled": true
}

Code Examples

Create a Skill

curl
curl -X POST https://skillslib.ai/api/v1/ext/skills \
  -H "Authorization: Bearer sk_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Contract Analyzer",
    "description": "Analyze legal contracts for risks and obligations.",
    "price": 12.99,
    "features": ["Clause extraction", "Risk scoring"],
    "tags": ["legal", "contracts"],
  }'
JavaScript (fetch)
const response = await fetch("https://skillslib.ai/api/v1/ext/skills", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_live_abc123...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "Contract Analyzer",
    description: "Analyze legal contracts for risks and obligations.",
    price: 12.99,
    features: ["Clause extraction", "Risk scoring"],
    tags: ["legal", "contracts"],
  }),
});

const skill = await response.json();
console.log(skill.id);
Python (requests)
import requests

response = requests.post(
    "https://skillslib.ai/api/v1/ext/skills",
    headers={"Authorization": "Bearer sk_live_abc123..."},
    json={
        "title": "Contract Analyzer",
        "description": "Analyze legal contracts for risks and obligations.",
        "price": 12.99,
        "features": ["Clause extraction", "Risk scoring"],
        "tags": ["legal", "contracts"],
    },
)

skill = response.json()
print(skill["id"])

Upload a SKILL.md File

curl
curl -X POST https://skillslib.ai/api/v1/ext/skills/clx.../upload \
  -H "Authorization: Bearer sk_live_abc123..." \
  -F "file=@./SKILL.md"
JavaScript (fetch)
const form = new FormData();
form.append("file", fs.createReadStream("./SKILL.md"));

const response = await fetch(
  "https://skillslib.ai/api/v1/ext/skills/clx.../upload",
  {
    method: "POST",
    headers: { "Authorization": "Bearer sk_live_abc123..." },
    body: form,
  }
);

const result = await response.json();
console.log(result.skillContentUpdatedAt);
Python (requests)
import requests

with open("SKILL.md", "rb") as f:
    response = requests.post(
        "https://skillslib.ai/api/v1/ext/skills/clx.../upload",
        headers={"Authorization": "Bearer sk_live_abc123..."},
        files={"file": ("SKILL.md", f, "text/markdown")},
    )

print(response.json())

Create a Promotion

curl
curl -X POST https://skillslib.ai/api/v1/ext/skills/clx.../promotions \
  -H "Authorization: Bearer sk_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "discountPercent": 25,
    "startsAt": "2026-08-01T00:00:00Z",
    "expiresAt": "2026-08-15T23:59:59Z",
    "title": "Summer Sale"
  }'
JavaScript (fetch)
const response = await fetch(
  "https://skillslib.ai/api/v1/ext/skills/clx.../promotions",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk_live_abc123...",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      discountPercent: 25,
      startsAt: "2026-08-01T00:00:00Z",
      expiresAt: "2026-08-15T23:59:59Z",
      title: "Summer Sale",
    }),
  }
);

const promo = await response.json();
console.log(promo.id);
Python (requests)
import requests

response = requests.post(
    "https://skillslib.ai/api/v1/ext/skills/clx.../promotions",
    headers={"Authorization": "Bearer sk_live_abc123..."},
    json={
        "discountPercent": 25,
        "startsAt": "2026-08-01T00:00:00Z",
        "expiresAt": "2026-08-15T23:59:59Z",
        "title": "Summer Sale",
    },
)

promo = response.json()
print(promo["id"])

Error Codes

When a request fails, the response body contains an error field with a human-readable message. Validation errors (400) also include a details array with per-field messages.

StatusMeaningExample Response
400Bad Request{ "error": "Validation failed", "details": [{ "field": "price", "message": "Must be a positive number" }] }
401Unauthorized{ "error": "Missing or invalid API key" }
403Forbidden{ "error": "Email not verified" }
404Not Found{ "error": "Skill not found" }
429Rate Limit Exceeded{ "error": "Rate limit exceeded", "resetAt": "2026-07-22T12:30:00Z" }
500Server Error{ "error": "Internal server error" }

Ready to start building?

Create an API key and start managing your skills programmatically.

Get Your API Key