TypeScript SDK
@mtp/sdk wraps the Platform API for Node.js services. It holds
your API key, exchanges it for a machine token on first use, caches the token until shortly
before expiry, refreshes single-flight, retries once on 401, and validates every response
against the same zod contracts the platform is built from.
import { MtpClient, MtpApiError } from '@mtp/sdk';
const mtp = new MtpClient({
baseUrl: 'https://api.train.hopemtp.app',
clientId: process.env.MTP_CLIENT_ID!,
clientSecret: process.env.MTP_CLIENT_SECRET!,
});Methods
| Method | Endpoint | Scope |
|---|---|---|
listContentItems({ type?, tag? }) | GET /content-items | content.read |
getContentItem(itemId) | GET /content-items/{id} | content.read |
findLearners(email) | GET /learners?email= | learners.read |
getLearner(learnerId) | GET /learners/{id} | learners.read |
enroll({ learnerId, courseItemId }) | POST /enrollments | enrollments.write |
getEnrollment(enrollmentId) | GET /enrollments/{id} | enrollments.read |
listEnrollments(learnerId) | GET /learners/{id}/enrollments | enrollments.read |
createSignInTicket({ learnerId, destination?, enrollmentId? }) | POST /sign-in-tickets | learners.sign_in |
scopes() | The scopes the token endpoint reported for this key | — |
Errors
Every failed call throws MtpApiError with status, code, message, and requestId
(when the API supplied one). Include the request id in support requests.
try {
await mtp.getLearner(id);
} catch (err) {
if (err instanceof MtpApiError && err.status === 404) {
// not a member of this organization
}
}Options
| Option | Default | Notes |
|---|---|---|
fetch | global fetch | Inject for tests or a proxying agent |
timeoutMs | 15000 | Per request |
tokenSafetyMarginSeconds | 30 | Refresh this early; tokens live 600 seconds |
The client holds a secret. Use it in server code only. Browsers get a learner session through
createSignInTicket, never a key.
Last updated on