Skip to content
code

Webhooks & API

Available

Build custom integrations using skillSYMS webhooks and REST API.

Overview

The Webhooks & API integration enables custom integrations with skillSYMS. Receive real-time event notifications via webhooks and interact with all skillSYMS data programmatically.

Webhooks

Available Events

EventTriggerPayload
learner.createdNew learner registeredLearner data
learner.updatedLearner record changedChanges
evidence.uploadedNew evidence submittedEvidence metadata
evidence.reviewedEvidence approved/rejectedStatus, feedback
assessment.recordedAssessment completedOutcome, learner
moderation.completedModeration doneDecision
export.readyExport generatedDownload URL

Webhook Configuration

Navigate to Settings β†’ Integrations β†’ Webhooks:

{
  "url": "https://your-system.com/webhooks/skillsyms",
  "secret": "whsec_...",
  "events": ["learner.created", "assessment.recorded"],
  "enabled": true
}

Webhook Payload

{
  "id": "evt_abc123",
  "type": "learner.created",
  "timestamp": "2024-12-01T10:30:00Z",
  "tenantId": "tenant-uuid",
  "data": {
    "id": "learner-uuid",
    "firstName": "Thabo",
    "lastName": "Mokoena",
    // ... learner data
  }
}

Signature Verification

Verify webhook authenticity:

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Retry Policy

Failed webhooks are retried:

  • Attempt 1: Immediate
  • Attempt 2: 5 minutes
  • Attempt 3: 30 minutes
  • Attempt 4: 2 hours
  • Attempt 5: 24 hours

After 5 failures, webhook is disabled.

REST API

Authentication

All API requests require authentication:

curl -X GET \
  https://api.skillsyms.com/v1/tenants/{slug}/learners \
  -H "Authorization: Bearer {api-key}"

API Key Management

Create API keys in Settings β†’ API Keys:

{
  "name": "Integration App",
  "role": "facilitator",
  "scopes": ["learners:read", "evidence:read"],
  "expiresAt": "2025-12-31"
}

Rate Limits

PlanRequests/minuteRequests/day
Pilot6010,000
Standard300100,000
EnterpriseCustomCustom

Rate limit headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1701430800

Pagination

List endpoints support pagination:

GET /api/v1/tenants/{slug}/learners?limit=50&offset=100

Response includes:

{
  "data": [...],
  "pagination": {
    "total": 1523,
    "limit": 50,
    "offset": 100,
    "hasMore": true
  }
}

Common Endpoints

Learners

GET    /api/v1/tenants/{slug}/learners
POST   /api/v1/tenants/{slug}/learners
GET    /api/v1/tenants/{slug}/learners/{id}
PATCH  /api/v1/tenants/{slug}/learners/{id}
DELETE /api/v1/tenants/{slug}/learners/{id}

Evidence

GET    /api/v1/tenants/{slug}/evidence
POST   /api/v1/tenants/{slug}/evidence
GET    /api/v1/tenants/{slug}/evidence/{id}
GET    /api/v1/tenants/{slug}/evidence/{id}/download
PATCH  /api/v1/tenants/{slug}/evidence/{id}

Assessments

GET    /api/v1/tenants/{slug}/assessments
POST   /api/v1/tenants/{slug}/assessments
GET    /api/v1/tenants/{slug}/assessments/{id}

Exports

POST   /api/v1/tenants/{slug}/exports
GET    /api/v1/tenants/{slug}/exports/{id}
GET    /api/v1/tenants/{slug}/exports/{id}/download

SDKs & Libraries

Official SDKs

Currently, we provide API documentation. SDKs are planned:

  • JavaScript/TypeScript SDK
  • Python SDK
  • C# SDK

OpenAPI Specification

Download our OpenAPI spec for code generation:

GET https://api.skillsyms.com/v1/openapi.json

Use with tools like:

  • OpenAPI Generator
  • Swagger Codegen
  • Postman

Error Handling

Error Response Format

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid SA ID number",
    "details": {
      "field": "saIdNumber",
      "reason": "Luhn check failed"
    }
  }
}

Error Codes

CodeHTTP StatusDescription
UNAUTHORIZED401Invalid or missing API key
FORBIDDEN403Insufficient permissions
NOT_FOUND404Resource not found
VALIDATION_ERROR400Invalid request data
RATE_LIMITED429Too many requests
SERVER_ERROR500Internal error

Best Practices

  1. Handle Errors: Implement proper error handling and retry logic
  2. Use Pagination: Don’t fetch all records at once
  3. Cache Responses: Reduce API calls where appropriate
  4. Verify Webhooks: Always verify webhook signatures
  5. Rotate Keys: Regularly rotate API keys
  6. Monitor Usage: Watch rate limits and errors

Support

For API support: