znanja API

Using this guide

This guide will make use of cURL. cURL is not required for interacting with this API, and it's use in this guide is purely demonstrative. cURL can usually installed by default on your Linux-based environment, or can be installed with

apt-get install curl  # Debian-based systems (Debian, Ubuntu)
yum install curl      # RedHat based systems (RHEL, CentOS, Fedora)
pacman -S curl        # ArchLinux

Instructions for Windows are not provided for the sake of this document, but can be found on the cURL website.

Important Note: Any library that allows you to make HTTP requests, and modify the request headers to include the Authorization header can be used. For example, python-requests can be used in Python, rest-client for Ruby, cURL PHP for PHP, System.Net.Http in .NET, or Apache HttpComponents in Java.

Important Note: In the $ curl examples, any trailing '\' character before a newline denotes line continuation.

About our API

API Versioning

Our API is versioned based on it's version in the path name. This API documentation is for version v1. If no version is given in the path, the most recent version of the API will be used. Additionally, we will confirm the API version number with a response header of

X-znanja-API-version: v1

You can use this to verify which version you are working with.

Existing versions

API Endpoint Locations

Version 1 API call are are sent to:

https://api.znanja.com/api/hawk/v1

If your Organization defines it's own sub-domain, calls cannot be made to that subdomain. That means, calls must be made to the above endpoint. Calls sent over http rather than https will be disregarded. This API requires use over HTTPS.

Request format

All requests that require sending additional information to the server must be sent as JSON. Additionally, you must pass your Content-Type as application/json.

Response format

All responses are JSON.

Status Codes

Normal HTTP status codes are returned, and their meaning is retained from the specification. For completion, the following codes are returned most frequently:

Authentication

The znanja API uses Hawk for authentication. Hawk "is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial HTTP request cryptographic verification".

Important Note: *The official Hawk client and server library is written in JavaScript. For unofficial ports in other languages, please see: https://github.com/hueniverse/hawk/issues?labels=port&page=1&state=closed. These language libraries are not the full znanja API library, but rather a helpful library that will take care of Authentication and verification. Understanding the below is still vital to using the znanja API.

Time Synchronization

In order to prevent certain types of "replay attacks", the znanja API requires some time synchronization between the API client and the znanja infrastructure. The znanja API requires synchronization of ±3 minutes.

To accommodate this, we highly recommend the use of NTP. Currently, znanja uses the following NTP servers maintained by National Research Council of Canada:

Any trusted NTP should work within that 6 minute time skew. If the times are not synchronized, the request will be disregarded.

Important Note: This does not require the times to be exactly the same (i.e. timezone). You can continue to use your own timezone, as long as NTP is used.

Credentials

The credentials you are given consist of the following:

Keep these credentials secret, as they are unique to you. Your credentials are tied directly to both your organization, and your user account. That is, the tuple (organization, user, key) is unique. This means, if you manage multiple organizations with your user account, that are in no way related to one and other via. a "managementship" you will need to generate multiple keys for each organization membership.

Generating an 'Authorization' header

The znanja API uses an Authorization HTTP header to validate requests that are sent to it. This header can be generated with Hawk.header() if you are using the Hawk client library, or otherwise as follows. If your credentials are:

And the current time is 1374546062, and you are sending a POST request to https://api.znanja.com/api/hawk/v1/users, with the body of the request the JSON string {"key": "value"} then your Authorization header passed must be:

Hawk id="some-organization-identifier", ts="1374546062", nonce="i2v02nvo", hash="tkSPNvcHGAh4c6F4sBmOz5AOZV9ebUrrVrOLigzDNOI=", mac="W1MfFWyncYytxOk5aP3ReoNVMzUmr7YF76Pc9e1YfAE=",

Important Note: The nonce is created on the client's end to prevent replay attacks. Please do not always use "i2v02nvo" as the nonce.

Generating a nonce

A nonce should be generated to be a random string. There are no restrictions on this string, however we suggest a random string of at least length 6. You must not re-used a nonce value.

Payload Validation (hash=)

In order to ensure full understanding between the server and the client, and to verify the requested action, znanja's API makes use of Payload Validation. This allows the API client to validate that the server interacted with the API in the way in which you intended. It can also be used as a quick way to verify the server, and that the API client is communicating to the machine it expects to be communicating with.

The hash= in the Authorization header is calculated using the hash algorithm that is used to calculate the mac= below. This value is then passed as the hash= portion of the Authorization header, which the server (and client) can use to verify the request payload. This value comes from calculating the hash using the algorithm given, and computing the hash of the following string:

hawk.1.payload
CONTENT-TYPE
PAYLOAD

for example, if your payload is: {"key": "value"}, and the hash algorithm is sha256, the above would be:

hawk.1.payload
application/json
{"key": "value"}

Giving you a hash of: tkSPNvcHGAh4c6F4sBmOz5AOZV9ebUrrVrOLigzDNOI=.

Be advised;

For example, in Python you would do:

from hashlib import sha256
from base64 import b64encode

hash_ = sha256()

hash_.update(b'hawk.1.payload\n\
application/json\n\
{"key": "value"}\n')

hash_digest = b64encode(hash_.digest())

Resulting in a payload hash of tkSPNvcHGAh4c6F4sBmOz5AOZV9ebUrrVrOLigzDNOI=

HMAC Signature Generation (mac=)

In order to make a request, the client must generate and pass into the Authorization header, the generated HMAC. This value comes from calculating the HMAC using the algorithm and the key, and computing the hash of the following string:

hawk.1.header
TIMESTAMP
NONCE
METHOD
RESOURCE
HOST
PORT
PAYLOAD_HASH

for example, in the above Authorization header, your string would be

hawk.1.header
1374546062
i2v02nvo
POST
/api/hawk/v1/users
api.znanja.com
443
tkSPNvcHGAh4c6F4sBmOz5AOZV9ebUrrVrOLigzDNOI=

Be advised;

For example, in Python you would do:

import hmac
from hashlib import sha256
from base64 import b64encode

mac = hmac.new(b's0m3sup3rs3cr3tk3y', digestmod=sha256)

mac.update(b"hawk.1.payload\n\
1374546062\n\
i2v02nvo\n\
GET\n\
/api/hawk/v1/users\n\
api.znanja.com\n\
443\n\
tkSPNvcHGAh4c6F4sBmOz5AOZV9ebUrrVrOLigzDNOI=\n\
\n")

mac_digest = b64encode(mac.digest())

Where mac_digest is the string value of mac= in the Authorization header, and is calculated to be W1MfFWyncYytxOk5aP3ReoNVMzUmr7YF76Pc9e1YfAE= Most languages provide an HMAC library already. It is highly suggested you use this library rather than implement your own.

Query Strings in URLs

Some API endpoints allow for additional query strings to be attached to the request to do things like pagination, searching, and filtering. These query parameters must be included in the URL portion used to generate the HMAC.

Validating the Server's Response

In addition to Payload Validation, the server will also send a Server-Authorization response header, which is similar to the request Authorization header. The Server-Authorization header includes the mac= in the response, which the server generates in the same method above, using the same string. This means, the response mac= will be identical to the request mac=.

The hash= portion of the header is generated similarly as above, except using the server's response payload, rather than the request payload. For example, if the server's response to the above POST request is:

{"username": "kr@example.com"}

Then the response hash= would be fivAvBQY65rn5+4o+tZYr5tZO1dlFL4ORfBV3DNYiDY=, making the response Server-Authorization header

Hawk mac="W1MfFWyncYytxOk5aP3ReoNVMzUmr7YF76Pc9e1YfAE=", hash="fivAvBQY65rn5+4o+tZYr5tZO1dlFL4ORfBV3DNYiDY="

Pagination

Some responses, specifically large lists, will be paginated. Pagination uses query strings to break down the responses that are sent. Query strings for paginations are:

If page and per_page are omitted, the default values will be used. Additionally, as a Response Header, we will send back a Pageable-Total header with the total number of resources that can be paginated over in this list.

To make a call to get a list of page 3 of the Organization's users, with 40 results per-page the URL would be: https://api.znanja.com/api/hawk/v1/users?page=3&per_page=40

Searching

Some lists can be searched using a similar mechanism as the Pagination above. This allows you to filter lists based on some criterion. To search append the query string search= to your endpoint URL. For example to search for user's with the name "Jon", the URL would be: https://api.znanja.com/api/hawk/v1/users?search=Jon.

The search query parameter can me mixed with the Pagination parameters to paginate the results.

Data types

Date/time strings

A value that specifies a date and optionally a time must be a string using a supported date/time format. While a variety of common date/time formats are accepted, it is recommended that date/time values use ISO 8901 format which is described below.

The date is required. The time and time zone are optional.

FormatDescriptionExample
YYYY-MM-DDDate only2000-01-02 (January 2, 2000)
YYYY-MM-DDThh:mm:ssZDate and time2000-01-02T03:04:05Z (January 2, 2000 at 3:04:05 AM UTC)
YYYY-MM-DDThh:mm:ss±zz:zzDate, time, and time zone2000-01-02T03:04:05-04:00 (January 2, 2000 at 3:04:05 AM AST)

Locale strings

A locale must be specified as string containing a language code. The following is a list of locales supported by the LMS. Values are case sensitive and must not contain any whitespace.

ValueDescription
enEnglish
frFrench
esSpanish
zh-CNChinese (Simplified)
zh-TWChinese (Traditional)
ruRussian
tlTagalog (Filipino)
iaEnglish - Alternate Terminology - Resources
ikEnglish - Alternate Terminology - Sessions

Resource types

The znanja API defines the following resource types

Messages

The API may return additional messages in its responses, particularly when an error occurs. A message is a JSON object containing the following values:

NameRequiredTypeDescription
typeNostringIndicates severity. Possible types are: success, info, warning, and error
forNostringThe name of a parameter that is primarily related to this message.
codeNostringA machine-readable error code for this message.
textYesstringA human-readable description.

For example:

{
    "type": "error"
    "for": "email",
    "code": "duplicate_email",
    "text": "That email address is already in use.",
}

It is not recommended to rely on messages for error handling in your application. Messages may change as we improve the platform.

As of August 2022, some endpoints may return message text (text) that is translated into the language used by the user calling the API. Some endpoints do not support translated text and will instead return message text in English.

As of August 2022, some endpoints may return an error code (code) which are more specific than HTTP status codes and are intended to be usable by your application's error handling. However, this is a beta feature. Error codes may change as we improve the platform.

Errors

Errors are represented in the znanja API as an Error resource along with the appropriate HTTP Status Code. Error Resources are JSON objects containing the following

{
    success: false,
    messages: [...]
}

Where messages is an array of message JSON objects described above.

Please do not rely on the messages array for your error handling, instead rely on the HTTP Status Code response.

Course

A Course resource represents an eLearning course. This is a high-level overview of a course and does not include specifics like the actual contents of the course.

Definition

A Course resource is a JSON object.

KeyTypeDescription
idintegerUnique identifier.
organization_idintegerID of the Organization resource that owns this course.
namestringCourse name.
section_namestringThe name of auto-numbered sections within this course.
descriptionstringCourse description.
objectivesstringCourse objectives.
in_storefrontbooleanWhether or not this course is for sale in the storefront.
in_storefront_carouselbooleanWhether or not this course is displayed in the storefront carousel.
pricefloatThe price listed for this course in the storefront.
durationintegerThe duration (in minutes) listed for this course in the storefront.
email_instructorbooleanWhether or not students can email their instructor.
instructor_emailstringThe email address that will receive emails from students to their instructor.
can_deletebooleanWhether or not you can delete this course.
can_editbooleanWhether or not you can edit this course.
can_exportbooleanWhether or not you can export this course.
Note: This is in general. More specific permissions determine if you have access to each type of export.
can_export_connectorbooleanWhether or not you can export this course as a connector-based SCORM package.
can_export_staticbooleanWhether or not you can export this course as a full, static SCORM package.
can_movebooleanWhether or not you can move this course to a different organization.
can_reportbooleanWhether or not you can generate reports for this course.
can_viewbooleanWhether or not you can view the content of this course.

If you have permission to generate reports for this course (can_report == true), then the following values are also included:

KeyTypeDescription
total_students_enrolledintegerThe number of students enrolled in this course.
total_students_in_progressintegerThe number of students enrolled who have started this course, but not finished.
total_students_completedintegerThe number of students enrolled who have viewed all pages in this course.

Example

{
    "id": 1,
    "organization_id": 2,
    "name": "My Course Title",
    "section_name": "Section",
    "description": "My course description.",
    "objectives": "My course objectives.",
    "in_storefront": true,
    "in_storefront_carousel": false,
    "price": 2.5,
    "duration": 30,
    "email_instructor": true,
    "instructor_email": "instructor@example.com",
    "can_delete": true,
    "can_edit": true,
    "can_export": true,
    "can_export_connector": true,
    "can_export_static": false,
    "can_move": true,
    "can_report": true,
    "can_view": true,
    "total_students_enrolled": 20,
    "total_students_in_progress": 12,
    "total_students_completed": 3
}

Page

A Page resource represents a single page within an eLearning course.

Definition

A Page resource is a JSON object.

KeyTypeDescription
idstringA unique identifier, based on the path to the page within the course's Table of Contents.
typestringAlways "page" for pages.
titletitleThe title of the page, as it appears in the Table of Contents.
auto_numberbooleanWhether or not this page is automatically assigned a section number.
filestringThe filename of the page's HTML contents, found in the course's zpackage.
rubricRubric resourceThe scoring rubric defined for this page.
required_progressintegerThe amount of progress required before a student can view this page.
required_scorefloatThe overall score required before a student can view this page.

The sign of required_progress determines how progress is compared:

The sign of required_score determines how score is compared:

Example

{
    "id": "0",
    "type": "page",
    "title": "Page 1",
    "auto_number": false,
    "file": "page1.html",
    "rubric": [],
    "required_progress": 0,
    "required_score": 0
}

Users

The User resource contains information about a single user within the znanja platform. Users are both administrators, non-administrator editor (i.e. editor, instructional designer, content creator). This access information can be found on the Membership resource. This contains useful information about the user themselves. A User resource is:

{
    "first_name": "First",
    "last_name": "Last",
    "is_active": true,
    "membership": {
                "is_active": true
    },
    "id": 1,
    "last_login": "2013-07-24T13:58:11.118370-03:00",
    "email": "email@example.com",
}

Of which, everything is self-explanatory, with the exception of membership. The membership key shows user's relationship with this organization. Is is_active is true, then the user belongs to the current organization.

As passwords are hashed, we have no way to return a user's password for this call.

Searching

User resources are searched by their last_name, first_name, and email fields.

Sorting

By default, User resources are sorted by name in asc order.

sort_by valueDescription
nameSort users by their last name, then first name, then email address.
emailSort users by email addresses.
last_loginSort users by the date they last logged in.
total_courses_assignedSort users by the number of courses in which they are enrolled.
total_courses_in_progressSort users by the number of courses they have started, but not finished.
total_courses_completedSort users by the number of courses in which they have viewed all pages.

User Instructor

A User Instructor resource is a relationship between a user and an instructor directly assigned to the user.

Definition

A User Instructor resource is a JSON object.

KeyTypeDescription
idstringA unique identifier.
organization_idintegerThe ID of the organization associated to this user instructor.
instructor_user_idintegerThe ID of the user who is the instructor.
instructed_user_idintegerThe ID of the user who is being instructed by the instructor.
date_createdDate/time stringThe date and time when the user instructor was created.

Example

{
    "id": "00000000-0000-0000-0000-000000000000",
    "organization_id": 1,
    "instructor_user_id": 2,
    "instructed_user_id": 3,
    "date_created": "2000-01-02T03:04:05Z"
}

Membership

A Membership resource is a relationship between a user and an organization. This allows the user to access content assigned to them by the organization. A membership also contains several role flags which, if enabled, will grant additional permissions to the user, such as administrative access.

Administrators of the organization can modify or revoke the membership at any time. A membership also allows administrators to modify details about the user.

If a membership is not active, all permissions between the user and organization are revoked.

Definition

A Membership resource is a JSON object.

KeyTypeDescription
user_idintegerThe ID of the User resource associated to this membership.
organization_idintegerThe ID of the Organization resource associated to this membership.
is_adminbooleanWhether or not the user is granted the administrator role within the organization.
is_instructional_designerbooleanWhether or not the user is granted the instructional designer role within the organization.
is_creatorbooleanWhether or not the user is granted the content creator role within the organization.
is_activebooleanWhether or not this membership is active. If inactive, all access to the organization by the user is revoked.
can_editbooleanWhether or not you can edit this membership.
Note: This is in general. More specific permissions determine what you can edit.
can_edit_apibooleanWhether or not you can generate API credentials for this membership.
can_edit_disablebooleanWhether or not you can set this membership as inactive.
can_edit_enablebooleanWhether or not you can set this membership as active.
can_edit_rolesbooleanWhether or not you can edit the role flags of this membership.
can_viewbooleanWhether or not you can view details about this membership.
can_view_apibooleanWhether or not you can view the API credentials associated to this membership.

Example

{
    "user_id": 1,
    "organization_id": 2,
    "is_admin": false,
    "is_instructional_designer": false,
    "is_creator": false,
    "is_active": true,
    "can_edit": true,
    "can_edit_api": true,
    "can_edit_roles": false,
    "can_edit_disable": false,
    "can_edit_enable": false,
    "can_view": true,
    "can_view_api": true
}

Group

A Group resource contains information about a group belonging to some organization. A group enrolls a set of students into a set of courses and those students can be managed by a set of instructors.

Definition

A Group resource is a JSON object.

KeyTypeDescription
idintegerA unique identifier.
organization_idintegerThe ID of the Organization resource that owns this group.
namestringThe name of the group.

Example

{
    "id": 1,
    "organization_id": 2,
    "name": "My Group"
}

Group Membership

A Group Membership resource contains information about the association between a user and a group. If such a resource exists, then the user is a member of a group either as a student or an instructor.

Definition

A Group Membership resource is a JSON object.

KeyTypeDescription
group_idintegerThe ID of a Group resource.
user_idintegerThe ID of a User resource.
is_instructorbooleanWhether or not the user is an instructor of this group.

Some endpoints may include the associated User resource in their response.

KeyTypeDescription
userUser resourceThe associated user.

Example

{
    "group_id": 1,
    "user_id": 2,
    "is_instructor": false
}

Organizations

An Organization resource represents an organization within the znanja platform. A Organization resource is:

{ "datecreated": "2012-10-26T12:38:54.306434-04:00", "domains": ["yourcompany.znanja.com", ...], "hasstorefront": false, "hastrainingpackage": true, "id": 1, "isactive": true, "isparentorg": false, "name": "Organization A" }

Courses

POST /course

Create a new Course resource. This course will contain a default set of assets and a title page. Your user account is also automatically enrolled in the new course.

Request

The request body must be a JSON object.

ParameterTypeDescription
namestringThe name of the course.
Default: Untitled course

Response

Status codeDescription
201 CreatedThe Course resource was created successfully.
Body: The new Course resource.
400 Bad RequestIf the request parameters are invalid or malformed.
403 ForbiddenIf you are not permitted to create courses for your organization.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", hash="F3wfUxCJVu21QsdUyX/Uvpa2ncGM30rIbVKaTf+IUFo=", mac="JHey+x2ql++FcRq1X/ZtAI6xwazPBHBzRh4NnDd53PM="' \
       --header 'Content-Type: application/json' \
       --data '{"name":"My New Course"}' \
       --url https://api.znanja.com/api/hawk/v1/course
HTTP/1.1 201 Created
...

{
    "id": 12345,
    "name": "My New Course"
    "section_name": "Section",
    ...
}

Pages

These endpoints implement operations for Page resources. The following markers are used in endpoint URLs:

MarkerTypeDescription
:course_idintegerThe ID of a Course resource.

GET /course/:course_id/pages

Generate a list of pages in a course. The order of the pages is the same as the Table of Contents, without any hierarchy.

Response

Status codeDescription
200 OKThe list was retrieved successfully.
Body: An array of Page resources.
403 ForbiddenIf you are not permitted to view the course.
404 Not FoundIf the course was not found.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="pMBSKE30+xPbnQH/6ezwe7Y0cfGAlfmkG8ptyDbMaYQ="' \
       --url https://api.znanja.com/api/hawk/v1/course/1/pages
HTTP/1.1 200 OK
...

[
    {
        "id": "0",
        "type": "page",
        "title": "Page 1",
        "auto_number": false,
        "file": "page1.html",
        "rubric": [],
        "required_progress": 0,
        "required_score": 0
    },
    ...
]

Users

GET /users

Generate a paginated list of users who are members of your current organization.

Request

This endpoint accepts [pagination][], [search][], and [sort][] parameters.

Response

Status codeDescription
200 OKThe list was retrieved successfully.
Body: An array of User resources.
403 ForbiddenIf you are not permitted to view a list of users for your organization.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="pQ1cTgg9PleK9Ni9mN6UJulML58k/VSM//TSxGx/Fd0="' \
       --url https://api.znanja.com/api/hawk/v1/users
HTTP/1.1 200 OK
...

[
    {
        "id": 1,
        "first_name": "First",
        "last_name": "Last",
        "membership": {
            "id": 2",
            ...
        },
        ...
    },
    ...
]

GET /user/:id

Return information with the user ID :id. :id can either be the numeric User resource id, or the User's email address. For example;

curl -H 'Authorization: Hawk id="some-organization-identifier", ts="1374546062", nonce="TgCmTtYaYQQefY3h2Qpgk6I6", mac="CrnOYbqRWaG0BABycOFXaTXCIVsIjzb1n/oRo1S2kLA="' \
    --url https://api.znanja.com/api/hawk/v1/user/1

The response is a single User resource.

This will return:

PUT /user

Create a new user in your organization. The new user will be added to your organization with an active membership. Optionally, the user may be sent a notification email containing their login details.

If a user already exists with the email address you provide, then a new user will not be created and the existing user will be added to your organization instead. Either an active membership will be created or their existing membership will be set to active. However, the existing user's details will not be updated. If the notification email is enabled, they will still receive an email.

Request

ParametersRequiredTypeDescription
first_nameYesstringThe user's first name.
last_nameYesstringThe user's last name.
emailYesstringThe user's email address. This is used when logging in and any notification emails will be sent to this address.
passwordNostringThe password the user must use when logging in. If not specified, then a random password will be generated.
password_confirmConditionalstringThis field is only required if a password has been specified. It must be the same as password.
bioNostringThe user's biography, such as a description of themself.
localeNoLocale string or nullThe user's language. When the user is logged in, the user interface for the LMS will be translated into this language. If not specified, the default language for your organization will be used.
expiryNoDate/time string or nullThe date and time when the user's account will expire.
notifyNobooleanIf true, then the user will be sent a notification email containing their login details. If false or not specified, an email will not be sent.

Response

If successful, the response body is a User resource. If an error occurs, the response body is an Error resource.

If a password was randomly generated, then the response body will include a password value. If you intend for the user to log in with this password and have not enabled the notification email, then your application must communicate the password to the user in some way. Otherwise, the user will not know their password.

Status codeDescription
200 OKA new user was created or an existing user was updated successfully.
400 Bad RequestIf the request parameters are invalid or malformed.
403 ForbiddenIf you are not permitted to create users.

Example

curl -H 'Authorization: Hawk id="some-organization-identifier", ts="1374546062", nonce="VtGDBScfn9foFpc1eMh49LIE", hash="O1k77kDf5LdE4GVyJ5+BJrkL79f640all152eQJBMEM=", mac="YqAHD6E9TLKlUDB0tbz6nF+Nba778PjmJHQmExkiwos="'\
    -X PUT -d "{\"first_name\":\"First\",\"last_name\":\"Last\",\"email\":\"user@example.com\",\"is_active\":true}"\
    -H "Content-Type: application/json"
    --url https://api.znanja.com/api/hawk/v1/user

POST /user/:id

Update a user in your organization.

Request

MarkerTypeDescription
:idnumber or stringThe ID or email address of the user to update.
ParametersRequiredTypeDescription
first_nameNostringThe user's first name.
last_nameNostringThe user's last name.
emailNostringThe user's email address. This is used when logging in and any notification emails will be sent to this address.
passwordNostringThe password the user must use when logging in.
password_confirmConditionalstringThis field is only required if a password has been specified. It must be the same as password.

Response

If successful, the response body is a User resource. If an error occurs, the response body is an Error resource.

Status codeDescription
200 OKThe user was updated successfully.
400 Bad RequestIf the request parameters are invalid or malformed.
403 ForbiddenIf you are not permitted to edit the specified user.

Example

curl -H 'Authorization: Hawk id="some-organization-identifier", ts="1374546062", nonce="-Wwv4cjp00A7a9TdJrJcK1Op", hash="u0C5rh1pNFrkIuc22WkChljfdDff4oGGAXF/or1yX24=", mac="oGYhWpAlWKFluVi/1FMUjKUJSNdQHc3mOl5tk/vWS3o="'\
    -X POST -d "{\"first_name\":\"Joe\",\"last_name\":\"User\",\"email\":\"joeuser@example.com\",\"is_active\":false}"\
    -H "Content-Type: application/json" \
    --url https://api.znanja.com/api/hawk/v1/user/1

DELETE /user/:id

Disable a User resource on znanja. The user ID :id. :id can either be the numeric User resource id, or the User's email address. Disabled Users are disabled only on your Organization, and may still be able to log in, if they are members of other Organizations, but will not be able to access your Organization. If your Organization is the Users only Organization, then the User will be disabled completely.

curl -H 'Authorization: Hawk id="some-organization-identifier", ts="1374546062", nonce="WTf3nKSCAD4mg4F-jYhSFKCS", mac="PjRzaRvwnOlpUn2fC7OQA4YRPBS71g7VVY9WdY6FyzM="' \
    -X DELETE
    --url https://api.znanja.com/api/hawk/v1/user/1

In response, you will get either:

Additionally, if the user is already disabled at the time of this call, we will return a 204 No Content. This means, 204 No Content confirms in any situation that the user has been disabled.

PUT /user/:id

Re-enable an existing User resource and the Membership defined by the Hawk credentials you are using. If the user is completely disabled, then the User and the Membership will be re-activated, so that the user can log in, and use the LMS as they could before.

curl -H 'Authorization: Hawk id="public_api:membership:4:42", ts="1377100470.095", nonce="Rbzd8SCRbtEuz2o0xB2ggckT", hash="NVuBm+XMyya3Tq4EhpZ0cQWjVUyIA8sKnySkKDOIM4M=", mac="Pqj96u+35zV0wQX1Fm13AFPQcIlrwsraAai6SZrJ67A="' \
-X PUT \
--url https://znanja.dev:6544/api/hawk/v1/user/18

In response, you will get either:

User Instructors

POST /user/:instructed_user_id/user-instructor/:instructor_user_id

Add a user instructor to a user.

This grants the instructor permission to view reports for the instructed user.

Request

MarkerTypeDescription
:instructed_user_idintegerThe ID of the user who the instructor will instruct.
:instructor_user_idintegerThe ID of the user who will be the instructor.

The user IDs must be different (instructors cannot instruct themselves). The request body must be empty.

Response

If successful, the response body is a User Instructor resource. If an error occurs, the response body is an Error resource.

Status codeDescription
200 OKThe instructor was added successfully.
400 Bad RequestIf the instructor and instructed user IDs are the same.
403 ForbiddenIf you are not permitted to assign the instructor to the user.
404 Not FoundIf the instructor or user were not found or are not members of your organization.
409 ConflictIf the instructor is already assigned to the user.
Error codeDescription
not_foundIf the instructor or user were not found or are not members of your organization.
edit_instructor_permissionIf you are not permitted to assign the instructor to any user.
edit_instructed_permissionIf you are not permitted to assign any instructor to the user.
self_referenceIf the instructor and instructed users IDs are the same.
duplicateIf the instructor is already assigned to the user.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="ziEqaBXavJfoG7N3AMvMRGLbVTtMAfeI+8+4k2OU3ts="' \
       --request POST \
       --url https://api.znanja.com/api/hawk/v1/user/1/user-instructor/2

HTTP/1.1 200 OK
...

{
    "id": "00000000-0000-0000-0000-000000000000",
    ...
}

DELETE /user/:instructed_user_id/user-instructor/:instructor_user_id

Remove a user instructor from a user.

The instructor will no longer be able to view reports for the instructed user.

Request

MarkerTypeDescription
:instructed_user_idintegerThe ID of the user who is instructed by the instructor.
:instructor_user_idintegerThe ID of the user who is the instructor.

The request body must be empty.

Response

If successful, the response body will be empty. If an error occurs, the response body is an Error resource.

Status codeDescription
204 No ContentThe instructor was removed successfully.
403 ForbiddenIf you are not permitted to remove the instructor from the user.
404 Not FoundIf no user instructor relationship was found.
Error codeDescription
not_foundIf no user instructor relationship was found.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="+88zNoltGep5eaRo1L6WUiK1TGw2yHBpquAxFdgGB/o="' \
       --request DELETE \
       --url https://api.znanja.com/api/hawk/v1/user/1/user-instructor/2

HTTP/1.1 204 No Content
...

Memberships

GET /membership/:user_id/:organization_id

Return information about the membership associated to the identified user and organization.

Request

MarkerTypeDescription
:user_idintegerAn ID of a User resource.
:organization_idintegerAn ID of an Organization resource.

Response

Status codeDescription
200 OKThe membership was found.
Body: The Membership resource.
403 ForbiddenYou do not have permission to view the membership.
404 Not FoundA membership does not exist between the user and organization.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="/qAAwuK5rccE4YZrYmpjVzZqylcRnQcE7sdpqgDi0Lo="' \
       --url https://api.znanja.com/api/hawk/v1/membership/1/2

HTTP/1.1 200 OK
...

{
    "user_id": 1,
    "organization_id": 2,
    "is_admin": false,
    ...
}

PUT /membership/:user_id/:organization_id

Modify the attributes of a Membership resource associated to the identified user and organization.

Request

MarkerType
:user_idinteger
:organization_idinteger

The request body must be a JSON object.

If you are able to modify the roles for the membership (can_edit_roles == true), then the following parameters are accepted:

ParameterType
is_adminboolean
is_instructional_designerboolean
is_creatorboolean

If you are able to disable (can_edit_disable == true) or enable the membership (can_edit_enable == true), then the following parameter is accepted:

ParameterType
is_activeboolean

You can only change is_active to false if you can disable the membership. Likewise, you can only change it to true if you can enable the membership.

Response

Status codeDescription
200 OKThe membership was modified successfully.
Body: The Membership resource.
400 Bad RequestThe request is malformed, the request parameters are invalid, or you do not have permission to change certain parameters.
403 ForbiddenYou do not have permission to edit the membership.
404 Not FoundA membership does not exist between the user and organization.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", hash="ZAJjR8tx9guOG0EtnX/UavnB+hubAUa3UfGlbXGc6Vo=", mac="KaUFETBEBY/zAzc0SXXvMueYDGexLQQkS9G81z1yNtU="' \
       --request PUT
       --header 'Content-Type: application/json' \
       --data '{"is_active":false}' \
       --url https://api.znanja.com/api/hawk/v1/membership/1/2

HTTP/1.1 200 OK
...

{
    "user_id": 1,
    "organization_id": 2,
    "is_active": false,
    ...
}

Groups

GET /groups

Generate a paginated list of groups that belong to your current organization.

Request

This endpoint accepts [pagination][], [search][], and [sort][] parameters. The name field will be searched. The default sort is on the name field in asc order.

sort_by valueDescription
nameSort groups by name.

Response

Status codeDescription
200 OKThe list was retrieved successfully.
Body: An array of Group resources.
403 ForbiddenIf you are not permitted to view a list of groups for your organization.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="ImYSPt4hfQ2Of1f5nb67MW5xEk2ShHBPtss+DLV/dno="' \
       --url https://api.znanja.com/api/hawk/v1/groups

HTTP/1.1 200 OK
...

[
    {
        "id": 1,
        "organization_id": 2,
        "name": "My group"
    },
    ...
]

GET /group/:group_id/users

Generate a paginated list of users in a group.

Request

This endpoint accepts [pagination][], [search][], [sort][], and [filter][] parameters.

Filter keyTypeDesciption
rolestringFilter list by either students, instructors, or available users that can be added to the group.
Possible values: students, instructors, or available

Response

Status codeDescription
200 OKThe list was retrieved successfully.
Body: An array of User resources.
403 ForbiddenIf you are not permitted to view a list of users for this group.
404 Not FoundIf the group was not found.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="cxiTIKNmfqPDRrzpL59PyZeivvUWWoPhSjRh5MApgR8="' \
       --url https://api.znanja.com/api/hawk/v1/group/1/users

[
    {
        "id": 1,
        "first_name": "First",
        "last_name": "Last",
        ...
    },
    ...
]

Group Memberships

These endpoints implement operations for Group Membership resources. The following markers are used in endpoint URIs:

MarkerTypeDescription
:group_idintegerThe ID of a Group resource.
:user_idintegerThe ID of a User resource.

GET /group/:group_id/memberships

Generate a paginated list of memberships in a group.

Request

This endpoint accepts [pagination][], [search][], [sort][], and [filter][] parameters. Searching and sorting applies to the related User resource.

Filter keyTypeDescription
rolestringFilter list by either students or instructors.
Possible values: students or instructors

Response

Status codeDescription
200 OKThe list was retrieved successfully.
Body: An array of Group Membership resources with associated User resources.
403 ForbiddenIf you are not permitted to view a list of memberships for the group.
404 Not FoundIf the group was not found.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="TQqnjKR/Erm+2mkXeCr+dRIYapx1FwfV3FDUf+ujBcw="' \
       --url https://api.znanja.com/api/hawk/v1/group/1/memberships

HTTP/1.1 200 OK
...

[
    {
        "group_id": 1,
        "user_id": 2,
        "is_instructor": false,
        "user": {
            "id": 2,
            "first_name": "First",
            "last_name": "Last",
            ...
        }
    },
    ...
]

POST /group/:group_id/membership/:user_id

Add a user to a group.

This will also automatically enroll the user into all courses that exist in the group.

Request

The request body must be a Group Membership resource. The group_id and user_id values must match the same values in the URL.

Response

Status codeDescription
201 CreatedThe Group Membership resource was created successfully.
Body The new Group Membership resource with the associated User resource.
400 Bad RequestIf the request parameters are invalid or malformed.
403 ForbiddenIf you are not permitted to add the identified user to any group or to add any users to the identified group.
404 Not FoundIf the user or group was not found.
409 ConflictIf the user is already a member of the group.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", hash="4GlBMpikzwEtLyLYP0kTiw9umOB0EMq0KO4sV4j9ghY=", mac="KME6d4Nk54U8rxRucgXDTBRXYLAKBGOPBi1UZElFU68="' \
       --header 'Content-Type: application/json' \
       --data '{"group_id":1,"user_id":2,"is_instructor":true}' \
       --url https://api.znanja.com/api/hawk/v1/group/1/membership/2

HTTP/1.1 201 Created
...

{
    "group_id": 1,
    "user_id": 2,
    "is_instructor": true,
    "user": {
        "id": 2,
        ...
    }
}

DELETE /group/:group_id/membership/:user_id

Remove a user from a group.

This also withdraws the user from all courses that they were enrolled in via the group, except for any courses that may still be assigned by a different group.

Response

Status codeDescription
204 No ContentThe Group Membership resource was deleted successfully.
403 ForbiddenIf you are not permitted to remove users from the group.
404 Not FoundIf the user was not found, the group was not found, or the user is not a member of the group.

Example

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="Y7hJBG8Se11blDMzw7Dzs7J+pwKkgiL3UO7Jnk9Vbt8="' \
       --request DELETE \
       --url https://api.znanja.com/api/hawk/v1/group/1/membership/2

HTTP/1.1 204 No Content
...

Vouchers

POST /voucher/:code/redeem

Redeem a voucher either for yourself, a user in your organization, or a new user.

It is not recommended to use this API with vouchers that have a set number of allowed courses (allowing the user to select a subset of courses from the pack instead of being enrolled in all courses in the pack). Course selection is outside the scope of this API since it requires users to log into the LMS in order to access the user interface for selecting courses. Further details are described in the Response section below.

Request

MarkerTypeDescription
:codestringThe code for the voucher to redeem.

The request body varies depending on which user you are redeeming a voucher for.

To redeem a voucher for yourself, the request body must be empty, null, or an empty JSON object.

To redeem a voucher for a specific user, you must specify which user either by their email address or their user ID. The user must be a member of your organization. The request body must be a JSON object containing one of the following parameters:

ParameterType
emailstring
user_idinteger

To redeem a voucher for a new user, you must specify information needed to create the user. The user will be added as an active member of your organization. The request body must be a JSON object with the following parameters:

ParametersRequiredType
first_nameNostring or null
last_nameNostring or null
emailYesstring
passwordYesstring

Response

The response body is an Error resource.

If you redeem a voucher for a new user, then the response body will include a user resource and a redirect path.

If you redeem a voucher that has a set number of allowed courses, then the response body will include a redirect path.

The redirect path is an absolute path. To obtain the full URL, you must prefix this path with https:// and the domain you prefer your users to use when accessing the LMS. It has the following behavior and requirements:

Redirecting the user is outside the scope of this API since the user must be logged into the LMS in order to access it. The following are some examples on how this can be accomplished:

Status codeDescription
200 OKThe voucher was redeemed successfully.
400 Bad RequestIf the request parameters are invalid or malformed.
403 ForbiddenIf you are not permitted to redeem a voucher for the specified user, the specified user has already redeemed the voucher, the voucher has expired, or the voucher has reached its maximum number of redemptions.
404 Not FoundIf the voucher code or user was not found.
Error codeDescription
invalid_jsonIf the request body contains invalid JSON.
invalid_bodyIf the request body is not empty, null, or an object.
not_foundIf the voucher code or user was not found.
non_memberIf the user is not a member of your organization.
create_permissionIf you do not have permission to create users for the current organization.
redeem_permissionIf you do not have permission to redeem the voucher for the specified user.
expiredIf the voucher has expired.
max_redemptionsIf the voucher has reached its maximum number of redemptions.
redeemedIf the user has already redeemed the voucher.
invalid_user_idIf the user ID is not a number.
long_first_nameIf a new user's first name is too long.
long_last_nameIf a new user's last name is too long.
duplicate_emailIf a new user's email address is already associated with an existing user.
long_emailIf a new user's email address is too long.
missing_emailIf no email address was specified when creating a new user.
missing_passwordIf no password was specified when creating a new user.
short_passwordIf a new user's password is not long enough.
KeyOptionalTypeDescription
userYesUser resourceThe created user, if one was created.
redirectYesstringAn absolute path where the user may need to be redirected to after redemption.

Examples

Redeeming a voucher for yourself:

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", mac="bWCYhaqCEDKE6y6UuT3uALjM79wIQfRmTIpu4xk1iNI="' \
       --request POST \
       --url https://api.znanja.com/api/hawk/v1/voucher/EXAMPLE/redeem

HTTP/1.1 200 OK
...

{"success": true}

Redeeming a voucher for an existing user:

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", hash="9fo2J8Jrdtlox+Xft755sQoBhOZt5G0QEKRtXMb6pps=", mac="64er0u8rKhRX6bm/6qPs4x5wixiWkGEJfAvu87B6YDE="' \
       --header 'Content-Type: application/json' \
       --data '{"email":"user@example.com"}' \
       --url https://api.znanja.com/api/hawk/v1/voucher/EXAMPLE/redeem

HTTP/1.1 200 OK
...

{"success": true}

Redeeming a voucher for a new user:

curl --header 'Authorization: Hawk id="example-id", ts="1234567890", nonce="example-nonce", hash="KS57yhipKF57f4Hf6MdZvQQBt4BDo44yiolpl0Lvb84=", mac="40q4/RYFWBetJ9hwgsBqf4sFA4yd+pOMnwiOL6FfBTI="' \
       --header 'Content-Type: application/json' \
       --data '{"first_name":"Test","last_name":"User","email":"user@example.com","password":"test123"}' \
       --url https://api.znanja.com/api/hawk/v1/voucher/EXAMPLE/redeem

HTTP/1.1 200 OK
...

{
    "success": true,
    "user": { ... },
    "redirect": "/lms/dashboard"
}