• Overview
  • Glossary
  • API Semantics
  • Personalized Practice API
  • Content Registry API
  • Personalization Primitives API
  • Analytics API
  • Object Model
  • Overview

    Sana Web API is the primary way to integrate with Sana to make your learning product more adaptive. With this guide, we explain and provide code examples for use cases like adding personalization to your practice feature or how to take advantage of Sana to gain insights into users behaviours.

    Click one of the API offerings below to get started or continue reading our API semantics. You can also have a look at our Demo Application to see how the Personalized Practice API works.

    Glossary

    Concept Description
    Asset An asset is the smallest unit a user interacts with. An asset can be an “exercise” or a section of “theory”.
    AssetBank The collection of all the assets of a partner constitutes the AssetBank of the partner.
    View A view is a collection of assets from the asset bank. It defines the context in which a user interacts with content. Any real-time modelling happens within a view.

    API Semantics

    This section explains the semantics of our Rest API. It includes common information that is valid for all the endpoints.

    API Endpoints

    The base URL for all our endpoints is https://api.sanalabs.com. Please note that non-secure access to the API is not available. All HTTP requests will be redirected to HTTPS automatically.

    Authentication

    A valid API key is needed to access the Sana Web API. Contact Sana Labs to get your own API key. Your API keys carry privileges for you to access Sana Web API, be sure to keep them secret. Do not share your API keys in publicly accessible places such as Github or client-side code.

    Sana Web API expects the API key to be included in all API requests to the server in a header that looks like the following:

    X-API-KEY: $API_KEY

    If the key is omitted or is wrong, you will get a 401 Unauthorized response to your request.

    To authorize, pass the X-API-KEY header

    curl
      -H "X-API-KEY: $API_KEY"
      https://api.sanalabs.com/v1/next-exercises
    
    

    Make sure to replace $API_KEY with your API key.

    Rate Limits

    There is no hard rate limit at the moment where Sana will drop your data. However, if you need to make requests at a rate exceeding 200 req/s, please contact Sana Labs first. Requests include all the endpoints of Sana Web API.

    Max Request Size

    The maximum request size is 16 KB per call without exception. You will get a 400 Bad Request if these limits are exceeded.

    Content-Type

    Sana Web API consumes and produces JSON data. The content-type header must be set to application/json when calling Web API endpoints.

    Errors

    All endpoints either result in success or an error. The API returns 200 or 201 for successful requests and relevant HTTP status code and an Error Response object in case of an error. See the Error Status Codes section for the HTTP Status Codes Sana Web API returns.

    Error Status Codes

    The Sana Web API uses the following error codes:

    Error Code Error Text Error Description
    400 Bad Request Your request is invalid.
    401 Unauthorized No API Key or your API key is wrong.
    404 Not Found The specified resource could not be found.
    405 Method Not Allowed You tried to access a resource with an invalid method.
    500 Internal Server Error There was a problem on the server side. Please try again later.
    503 Service Unavailable The API is temporarily offline for maintenance. Please try again later.

    Personalized Practice API

    Personalized Practice API allows you to easily customize exercise-based practice sessions, such as review sessions, to the progress made by the individual user. You can simply request what exercise to present next, given that the outcomes of previously completed exercises have been posted to Sana Labs. The API allows you to specify a content filter and practice mode for every recommendation.

    Have a look at our Demo Application to see how the API works.

    In the Personalized Practice API, exercises can be requested one at a time, allowing the system to adapt to the most recent outcome, as visualized below.

    Personalized Practice Single Image

    Another option is to request a sequence of exercises (the next "quiz" or "session") in a single call and post back the outcomes either in one batch or one-by-one as they are completed.

    Personalized Practice Batch Image

    Posting User Events

    Posts user events to Sana. Posting of events is required for Sana to make personalized recommendations of what exercises to display next. The following event types are currently supported in the Personalized Practice API:

    Event Type Description
    response_submit Should be sent whenever a user has completed an exercise.
    theory_viewed Should be sent whenever a user has viewed a theory asset.

    All user events are sent through the same API endpoint. However each event has its own unique attributes.

    Endpoint

    POST /v1/user-events

    Body Parameters

    Key Mandatory Type Description
    user_events Yes Array of User Event objects The user events to post.

    Response Format

    On success, the HTTP status code in the response header is 200 OK and the response body is empty. On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Example

    curl "https://api.sanalabs.com/v1/user-events"
      -H "Content-Type: application/json" \
      -H "X-API-KEY: $API_KEY" \
      -X POST \
      -d '{
        "user_events": [{
                "user": {
                    "id": "123",
                    "type": "learner"
                },
                "type": "theory_viewed",
                "timestamp": "2018-01-05T15:11:30Z",
                "attributes": {
                    "view_id": "ABC",
                    "asset_id": "abc",
                    "time_spent_ms": 7050
                }
            },
            {
                "user": {
                    "id": "123",
                    "type": "learner"
                },
                "type": "response_submit",
                "timestamp": "2018-01-05T15:11:36Z",
                "attributes": {
                    "view_id": "ABC",
                    "asset_id": "abd",
                    "exercise_type": "multiple_choice",
                    "result": "correct",
                    "score": 1,
                    "time_spent_ms": 4100
                }
            }
        ]
    }'
    

    Getting Next Assets

    Gets recommended sequence of assets to present next.

    Endpoint

    POST /v1/next-assets

    Body Parameters

    Key Mandatory Type Description
    user Yes User object The User object that uniquely identifies a user.
    view_id Yes String ID of the view for which the practice is carried out.
    filter Yes Asset Filter object Specifying the subset of assets within the view that can be selected from. I.e. the filter expresses the focus of the practice in terms of available content.
    mode Yes Mode object Defines the mode or “purpose” of the session.
    limit Yes Integer The number of assets to return.

    Response Format

    On success, the HTTP status code in the response header is 200 OK and the response body as below.

    Key Type Description
    data An array of Asset Reference objects The recommended sequence of assets to present to the user.

    On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Example

    Request

    curl "https://api.sanalabs.com/v1/next-assets" \
      -H "Content-Type: application/json" \
      -H "X-API-KEY: $API_KEY" \
      -X POST \
      -d '{
        "user": {
            "id": "123",
            "type": "learner"
        },
        "view_id": "ABC",
        "filter": {
            "asset_types": ["exercise"],
            "view_paths": ["/math/algebra"],
            "tags": [{
                "name": "exam_year",
                "value": "2017"
            }, {
                "name": "exam_year",
                "value": "2018"
            }]
        },
        "mode": {
            "type": "review",
            "attributes": {}
        },
        "limit": 1
    }'
    

    Response

    '{"data": [{"asset_id": "A1"}, {"asset_id": "A2"}]}'
    

    Getting User Status

    Get a user's status by view and view path.

    Endpoint

    GET /v1/user-status

    Query String Parameters

    Key Mandatory Type Description
    user_id Yes String ID of the user.
    view_id Yes String ID of the view for which status is queried.
    view_paths Yes Array of Strings Paths within the view for which the user status is queried.

    Response Format

    On success, the HTTP status code in the response header is 200 OK and the response body as below.

    Key Type Description
    data Array of User-Path Status objects. The status of the user for the respective path wihtin the view queried.

    On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Content Registry API

    To get real-time recommendations from the Personalized Practice API, it is required that a registry of the available assets is exported to Sana Labs and put into a view.

    The Asset Bank contains a registry of all your content’s metadata, i.e. the content itself does not have to be exported to Sana Labs just references to the available assets and any available metadata (tags). The tags can be used for filtering and selection as well as for algorithms and analytics.

    A view is a collection of assets from the asset bank. It defines the context in which a user interacts with content. Any real-time modelling happens within a view. Any next asset recommendations happen within a view. Also response submit events should be posted with a view.

    Content Registry Overview

    Asset Management

    In order to work with views, it is required to create a registry of assets.

    Create / Update an Asset

    Creates or updates the provided asset. If the provided asset_id doesn’t exist in Sana Content Registry, the asset is created, else the asset is updated with the provided parameters in the body.

    Endpoint

    PUT /v1/assets/<asset_id>

    Body Parameters

    Key Mandatory Type Description
    type Yes String The type of asset, one of exercise or theory. The asset type defines the expected structure of the properties object.
    tags No Array of Tag objects Any free-form tagging of asset. Can be used for retrieval/filtering in API.
    description No String Any free-form description of the asset (maximum 5000 characters). For exercises and shorter theory sections it is recommended to put the whole question or theory text into the asset description. This information can be used for content analysis.
    content_url No String If it is possible to access the actual content by a URL, it is recommended to provide this information.
    attributes Yes Object The attributes object corresponding to the specific asset type, should be one of Theory Asset Attributes and Exercise Asset Attributes.

    Response Format

    On success, the HTTP status code in the response header is 200 OK and the response body is empty. On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Delete an Asset

    Endpoint

    DELETE /v1/assets/<asset_id>

    Response

    On success, the HTTP status code in the response header is 200 OK and the response body is empty. On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Get an Asset

    Endpoint

    GET /v1/assets/<asset_id>

    Response Format

    On success, the HTTP status code in the response header is 200 OK and the response body is an Asset Defintion object. On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Bulk Create / Update

    Lets you to bulk create or update assets. This is useful if the content registry is large and many elements have to be created / updated.

    Endpoint

    PUT /v1/assets

    Body Parameters

    Key Mandatory Type Description
    assets Yes Array of Asset Definition objects. The items to be created/updated. It is possible to create/update a maximum of 100 assets per call.

    Response Format

    On success, HTTP Status Code 200 OK with an empty body. This means that all the individual assets have been successfully created / modified. This operation is atomic, meaning that either all individual items are created/updated or none of them are created/updated. On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Bulk Delete

    Lets you delete items in bulks. The items will be deleted if they exists.

    Endpoint

    DELETE /v1/assets

    Query String Parameters

    Key Mandatory Type Description
    asset_ids Yes Array of Strings The asset IDs to be delted.

    Response Format

    On success, HTTP Status Code 200 OK and the response body is as below. This means that all the individual assets have been successfully deleted. This operation is atomic, meaning that on success all individual items are deleted and on failure none of them are deleted. Note that non-existing asset_ids are ignored and not considered an error.

    Key Type Description
    asset_ids Array of Strings The asset IDs that were deleted. If IDs for assets that does not exist are passed in request body, they will not be found in this list.

    On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Get Multiple Assets

    Lets you get multiple assets.

    Endpoint

    GET /v1/assets

    Query String Parameters

    Key Mandatory Type Description
    asset_ids Yes Array of Strings IDs of the assets to be queried. It is possible to query a maxium of 100 assets in a single call.

    Response Format

    On success, HTTP Status Code is 200 OK and the response body as below. This means that all the queried assets have been successfully fetched.

    Key Type Description
    assets Array of Asset Definition objects The assets queried.

    On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Views Management

    A view is a collection of assets from your asset bank. A view can represent hierarchical structure as well as (optionally) the default sequential order of the assets. The structure defined in a view is used to express the focus of personalized practice sessions and is also utilized by the recommendation algorithm. A view defines the context in which a user interacts with content - allowing the recommendation algorithm to model assets differently in different views. Any real-time modelling for next-asset recommendations happens within a view, but content insights can also transferred between views regularly.

    There is currently a limit of 1000 assets in a view, so it is important to select a reasonable split of your content into different views based on this.

    Create / Update a View

    Lets you create or update a view with the provided assets. If a view with the provided id already exists, the view will be updated, else it will be created. Note that a reference to all assets that belong to this view should be provided when creating or updating a view.

    Endpoint

    PUT /v1/views/<view_id>

    Body Parameters

    Key Mandatory Type Description
    name Yes String The name of the view.
    description No String A description of the view.
    ordered No Boolean Specifies if there is a default ordering of the assets in the view.
    assets Yes Array of View Item objects The assets in this view. If there is a default sequential ordering of the content it should be represented by the order of assets and ordered should be set to True.

    Response Format

    On success, the HTTP status code in the response header is 200 OK and empty body. On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Delete a view

    Deletes the view with the provided id.

    Endpoint

    DELETE /v1/views/<view_id>

    On success, the HTTP status code in the response header is 200 OK and empty body. On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Get a view

    Gets the view with the provided id.

    Endpoint

    GET /v1/views/<view_id>

    Response Format

    On success, HTTP Status Code is 200 OK and the response body as below.

    Key Type Description
    id String The ID of the view.
    name String The name of the view.
    description String The description of the view.
    ordered Boolean Specifies if there is a default ordering of the assets in the view.
    assets Array of View Item objects The assets in this view.

    On error, the header status code is an error code and the response body contains a list of Error Response objects.

    Personalization Primitives API

    The Personalization Primitives API lets you query the high-level properties that Sana predicts to personalize content to the user. Here are some examples of the information available:

    Analytics API

    The Analytics API lets you retrieve Analytics data to automate complex reporting tasks and build custom dashboards. With the Analytics API you can for example:

    Object Model

    This section describes the objects that are used throughout the different endpoints.

    Asset Definition

    Key Mandatory Type Description
    id Yes String An ID that uniquely identifies the asset.
    type Yes String The type of asset, one of exercise or theory. The asset type defines the expected structure of the properties object.
    tags No Array of Tag objects Any free-form tagging of asset. Can be used for retrieval/filtering in API.
    description No String Any free-form description of the asset (maximum 5000 characters). For exercises and shorter theory sections it is recommended to put the whole question or theory text into the asset description. This information can be used for content analysis.
    content_url No String If it is possible to access the actual content by a URL, it is recommended to provide this information.
    attributes Yes Object The attributes object corresponding to the specific asset type, should be one of Theory Asset Attributes and Exercise Asset Attributes.

    Tag

    Key Mandatory Type Description
    name Yes String Denotes the meaning or category of the tag.
    value Yes String Denotes the value of the tag.

    Theory Asset Attributes

    Key Mandatory Type Description
    theory_type No String The type of theory (if applicable).

    Additional asset metadata kan be added to attributes (allowed types are String and Number).

    Exercise Asset Attributes

    Key Mandatory Type Description
    exercise_type No String The type of exercise (e.g. multiple_choice).
    Advanced Attributes

    Key Mandatory Type Description
    variability No Integer The number of unique ways the exercise can be generated, in case of variable exercises. Defaults to 1 meaning the the exercise is always displayed the same way. If the exercise is "generated" in such a way that it is not displayed the exact same way to the user (e.g. by using a template with variable fields), variablity should be greater than 1. The value should be capped at 1000 (in case of larger, or infinite, number of unique instances).

    Additional asset metadata kan be added to attributes (allowed types are String and Number).

    View Item

    Key Mandatory Type Description
    asset_id Yes String ID of the asset.
    view_path Yes String Defines the location of the asset in the view's content hierarchy using the same standard as for location of files in a file system: /path/to/location, i.e. / is used as separator between parent "directories".
    attributes No View Item Attributes Object Additional attributes describing the asset's role within the view.

    View Item Attributes

    Key Mandatory Type Description
    partner_difficulty No Number If there is metadata expressing the difficulty of exercises, this can be provided in the View Item. It can be utilized by the recommendation algorithm in cold-start scenarios when there is little or no historical interaction data available. The partner_difficulty should be a number between 0 and 1, scaled so that 0 corresponds to the lowest difficulty level and 1 to the highest.

    User Event

    Key Mandatory Type Description
    user Yes User Object The relevant user for the event.
    type Yes String The event type, one of response_submit and theory_viewed.
    attributes Yes User Event Attributes Object The attributes of the event. The expected fields of attributes are tied to the specific event type.
    timestamp Yes String ISO 8601 timestamp of when exercise was completed.

    User

    Key Mandatory Type Description
    id Yes String An ID that uniquely identifies the user.
    type No String The type of user. One of learner and tester. Defaults to learner.

    Response-Submit Event Attributes

    Expected structure of User Event attributes when type is response_submit.

    Key Mandatory Type Description
    view_id Yes String The ID of the relevant View for the event.
    asset_id Yes String The ID of the asset.
    result Yes String Denotes if the exercise was successfully completed. One of correct, incorrect, partially_correct and skipped.
    score No Float The score of the given response (if exercises support partial scoring). The score should be normalized to a value between 0 and 1, based on minimum and maximum score of the exercise.
    time_spent_ms No Integer The time spent on solving the exercise in milliseconds.

    Theory-Viewed Event Attributes

    Expected structure of User Event attributes when type is theory_viewed.

    Key Mandatory Type Description
    view_id Yes String The ID of the relevant View for the event.
    asset_id Yes String The ID of the asset.
    time_spent_ms No Integer The time spent on solving the exercise in milliseconds.

    Asset Filter

    Key Mandatory Type Description
    asset_types Yes Array of Strings Only asset with at least one of specified types will be retured.
    view_paths Yes Array of Strings The location of the asset in the view hierarchy (as specified by view_path parameter of Asset Definition). The returned assets will be from one of the paths specified. It is possible to specify the path to any level in the hierarchy. If there for example are three topics under a specific subject "/subject_1/" you can get exercises recommended from subject_1 either by specifying ["/subject_1/"] or ["/subject_1/topic_1", "/subject_1/topic_2", "/subject_1/topic_3"].
    tags No Array of Tag objects Only asset with at least one of specified tags will be retured.

    Mode

    Key Mandatory Type Description
    type Yes String The mode of the personalized practice session. One of review and learn.
    attributes Yes Object Any attributes further parameterizing the practice mode.

    Learn Mode Attributes

    The "learn" mode is the most general mode. It guides the user through the content specfied by the filter object with an adaptive rate of progress and also seamlessly mixes in previously covered concepts when deemed necessary

    Review Mode Attributes

    The "review" assets are only recommended from previously covered concepts with the goal of maximising the learners reacall of what has been covered so far.

    Asset Reference

    Key Type Description
    asset_id String The ID of the asset referenced.
    asset_type String The type of the asset referenced.

    User-Path Status

    Key Type Description
    user_id String The ID of the user for which the status is valid.
    view_path String The path within the view for which status is valid.
    status User Status object The status of the user for the give view and view_path.

    User Status

    Key Type Description
    skill_level Number The skill level of the user, a value between 0 and 1.

    Error

    Key Type Description
    status int HTTP Status code related to this error.
    detail string Details of the error.
    link string URL to read more about this error.

    Error Response

    Key Type Description
    errors An array of Error Objects Errors associated with this request.