docsv1 ProductChangelogGet an API key

Build on the API the fkra apps run on.

The studio, the player, and the admin area read and write through one REST API. Your service calls the same endpoints for organizations, paths, modules, and progress.

zsh · fkra api
{ "statusCode": 200, "data": { "isRevoked": false, … } }
/api/v1200 OK
POST/public/user/login/credentialsign inPOST/shared/user/refreshrotate tokensGET/shared/user/profilecurrent userGET/user/learning/pathspublished pathsGET/public/certificate-verify/:codeverify a certificate
every app surface, same endpoints

If the apps can do it, the API can too

DocsDevelopersIntroduction

The fkra API

One REST API behind every fkra surface. Same objects, same permissions, same audit trail, whether the call comes from the studio, the player, or your own service.

Base URLhttps://<your-api-host>/api/v1Authx-api-key · BearerContentapplication/json

NoteEach snippet shows a request and the response it returns. Non-production deployments serve the full OpenAPI reference at /docs.

Quickstart

#

Three calls, from sign-in to content. Sign in, read the current user, then list the learning paths.

Send the email and password, get back an access token and a refresh token. The call also needs a solved CAPTCHA token. Accounts with two-factor on get a challenge instead of tokens.

login.sh
curl -X POST "https://<your-api-host>/api/v1/public/user/login/credential" \  -H "Content-Type: application/json" \  -H "x-api-key: $FKRA_KEY:$FKRA_SECRET" \  -H "x-captcha-token: $CAPTCHA_TOKEN" \  -d '{ "email": "amina@acme.edu", "password": "…", "from": "website" }'
POST/api/v1/public/user/login/credential200 OK
Body parameters
FieldTypeDescription
emailrequiredstringThe account's email address.
passwordrequiredstringThe account's password.
fromrequiredenumwebsite or mobile, depending on where the sign-in happens.

Authentication

#

Signed-in calls carry two credentials. The API key identifies your app and goes on every request; the access token identifies the user and goes on every route behind sign-in.

shell
curl "https://<your-api-host>/api/v1/shared/user/session/list" \  -H "x-api-key: $FKRA_KEY:$FKRA_SECRET" \  -H "Authorization: Bearer $ACCESS_TOKEN"
accessTokenAn ES256-signed JWT. Send it as Authorization: Bearer; expiresIn says how many seconds it lives.refreshTokenAn ES512-signed JWT, accepted only by the refresh endpoint. Each refresh rotates the pair, and the session keeps the expiry it got at sign-in.

CarefulThe secret is shown once, when an admin creates the key. Keep it on your server, and reset the key from /admin/system/api-keys.

Define your own module types

#

An admin registers a module type with two JSON schemas, one for its settings and one for its content. The studio builds its editing forms from them.

module-type.json
{  "key": "practice.branching_scenario",  "learnerAction": "Decide",  "configSchema": {    "properties": {      "branches": { "type": "array", "minItems": 2 },      "endings":  { "type": "array", "minItems": 2 },      "scoring":  { "enum": ["rubric", "points"] }    }  },  "bodySchema": {    "properties": { "persona": { "type": "string" } }  }}
Rendered in the studio
branching_scenarioSev-1 at 3am
personaon-call-engineerbranches4endings3scoringrubric
fkra/admin/content/module-typelive

Organizations, roles, and permissions

#

Each organization is its own tenant on its own subdomain. Protected routes check the user's role, then a permission written as a subject and an action, and both are read fresh on every request.

Tenantacme-academy.fkra.ai019f6a2e-…
Permission
learningModule · publishPublish modules
apiKey · createCreate and reset API keys
assessment · updateStart, answer, and submit assessments
Members, content, and activity in acme-academy are stored under its organization id./admin/system/roles · live

Arabic and English, built in.

#

Every surface ships in Arabic and English with right-to-left layout: content, dashboards, certificates.

Send x-custom-lang: ar and the message comes back in Arabic, with metadata.language set to match. Learner content routes read Accept-Language and report which locale they served, with a flag when they fell back to another.

ENReading our codebasev4.2 · approved
01Absorb12 min02Connect09 min03Evaluate06 min04Practice18 min
Readiness72%
ARقراءة قاعدة الكود لديناالإصدار 4.2 · معتمد
01استيعاب12 د02ربط9 د03تقييم6 د04ممارسة18 د
الجاهزية72%

Endpoints

#

Eight endpoints to start with, from sign-in to certificate checks. The fkra apps call the same ones. Open one to see what it needs and what it returns.

Requiresx-api-key · x-captcha-tokenReturnsUserLoginResponseDto
{ "isTwoFactorEnable": false, "tokens": { "tokenType": "Bearer", "expiresIn": 3600, … } }
Every other route, with its request and response schemas, is in the OpenAPI reference at/docs

Responses and paging

#

Every response carries a numeric status code, a message in the caller's language, request metadata, and the data. Paginated lists add their paging state to the metadata.

ParameterExampleMode
page1offset
perPage20offset · cursor
cursormetadata.nextCursorcursor
searchaminaoffset · cursor
orderBycreatedAt:descoffset · cursor
metadata on a cursor page
"metadata": {  "language": "en",  "path": "/api/v1/shared/user/session/list",  "version": "1",  "type": "cursor",  "perPage": 20,  "hasNext": true,  "hasPrevious": false,  "nextCursor": "eyJ…",  "orderBy": [{ "createdAt": "desc" }],  "availableOrderBy": ["createdAt", "updatedAt"]}

Errors and limits

#

Errors use the same envelope. The HTTP status names the kind of failure, and statusCode in the body is fkra's own code for the exact cause. Validation failures add an errors array with one entry per field.

4015100 · 5102The API key is missing, malformed, or expired, or its secret does not match.
4015120 · 5041The access token is missing or expired, or its session was revoked.
4035101No active API key matches.
4035063 · 5180The user's role or permissions do not cover this route.
4036104The user has not accepted the current terms of service and privacy policy.
4225030The body or query failed validation.
429429Too many requests from this client. Wait for Retry-After.
5035000The token could not be checked right now. Retry the request.
a validation error
HTTP/1.1 422 Unprocessable Entity {  "statusCode": 5030,  "message": "There are validation errors.",  "metadata": { "language": "en", "version": "1", … },  "errors": [    {      "key": "isNotEmpty",      "property": "password",      "message": "password cannot be empty."    }  ]}

Limits100 requests every 10 seconds, counted per client address, not per key. Past that the API answers 429 with a Retry-After header in seconds. Certificate checks have their own limit of 60 a minute.

An audit trail

#

Sign-ins, content edits, role and API key changes, and issued certificates are logged with the user, the action, the IP address, and the device. Failed attempts are logged too, and admins can export role events as CSV.

GET /api/v1/admin/activity-log/list3 events
14:02:11learningModuleUpdatedpolicy-v4-2amina@acme.edu14:02:48userLoginCredentialwebsite · 10.4.2.18noor@acme.edu14:07:44adminApiKeyCreatepartner-syncamina@acme.edu

The rest of the platform

#

Every workspace gets all of it.

AnalyticsEngagement, readiness, and completion, live per teamNotificationsAchievements and certificates land the moment they are earnedDiscoverA storefront for everything your organization teachesCommunitiesPractice groups, events, polls, and module discussionsGamificationPoints, badges, streaks, and verifiable certificatesMedia timelineChapters, cues, bookmarks, and notes on every videoLearning pathsStages, prerequisites, and outcomes, sequenced by difficultyAssessmentsAn authoring wizard, timed runs, server-side grading

Build on fkra

#

Straight to the founders, with no sales sequence and no qualification form. hello@fkra.ai

Explore more