Two or more clients creating orders for the same customer
Service Provider that doesn't manage license keys
Order containing bundle articles
The working group BOL, Beställa och Leverera (Order and Deliver) was given the assignment of developing an APIs that enables clients and service providers to exchange data to order and deliver digital educational resources.
BOL enables a client to offer the customer a client account in a license portal where the customer gets an overview of and can administer their purchased digital educational resources.
Example of BOL as part of an infrastructure.
To order digital educational resources. The client has to in another way know the article numbers of the service provider's articles. Bokinfo is one source of this.
To assign licenses of educational resources to end users. Both the client and the service provider have to know the same unique user id, probably synced from another system.
An assignment can be made by the client who placed the order or by the service provider. The client gets information about the assignments made by the service provider by calling endpoint /v1/school-units/users/licenses.
Endpoint | Method | Description | Mandatory |
---|---|---|---|
/v1/orders/create | POST | Used by the client to place an order at the service provider. | To order |
/v1/assignments/create | POST | Used by the client to do one or more assignments of a license to a user. A prerequisite is that the users have the same unique ID at the client as at the service provider. | To assign |
/v1/assignments/delete | POST | Used by the client to delete one or more assignments of a license to a user. A prerequisite is that the users have the same unique ID at the client as at the service provider. | No |
/v1/users/licenses | POST | Used by the client to get which licenses/articles are assigned to a specific user. A prerequisite is that the users have the same unique ID at the client as at the service provider. | No |
/v1/school-units/users/licenses | POST | Used by the client to get which licenses/articles are assigned to which users for a specific school unit. It also returns all unassigned licenses. A prerequisite is that the users have the same unique ID at the client as at the service provider. | To assign |
/v1/school-units/licenses | POST | Used by the client to get license status per article for specific school units. | No |
Authentication is primarily done through mutual TLS (e.g. using Skolfederation Moa when possible), but can also be done via tokens (RFC 7519) or API keys in the HTTP header.
All calls are done with HTTP POST if nothing else is specified.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
To respond to a request that is processed, always use HTTP Response Status Code 200 OK and use the field "status" and, if needed, "errorMessage" in the json response.
Requests that can’t be processed for any reason should be handled via an applicable not-successful HTTP Status Code (anything outside of the 2XX range) together with an application/problem+json response message giving further details:
https://www.rfc-editor.org/rfc/rfc9457.html
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{
"type": "https://tools.ietf.org/html/rfc7231\#section-6.5.8",
"title": "Bad Request",
"status": 400,
"errors": {
"orderLines": "Order lines must contain at least one item"
}
}
Order with the same key has previously been created:
HTTP/1.1 409 Conflict
Content-Type: application/problem+json
{
"type": "https://tools.ietf.org/html/rfc7231\#section-6.5.1",
"title": "Conflict",
"status": 409,
"detail": "Conflict: clientOrderNumber must have a unique value."
}
Something unexpected happened:
HTTP/1.1 500 Internal Server Error
Content-Type: application/problem+json
{
"type": "https://tools.ietf.org/html/rfc7231\#section-6.6.1",
"title": "Internal Server Error",
"status": 500,
"detail": "Unknown error occurred."
}
Service providers sometimes map data from one school (unit) to another usually to manage school unit groups.
If the service provider maps data to another school (unit), the service provider must save the original school id that the client sent on the submitted data in order to respond to the client with the original id in later requests and responses.
The service provider must save the clientOrderLineId on the order line. clientOrderLineId is then used in later requests and responses.
The service provider must be able to handle orders coming in from several clients. Each client can only assign the licenses that they themselves ordered. All licenses can be assigned by the service provider.
If the service provider does not manage license keys, the article number is entered. As there may be several ordered articles with different license lengths, the client must also specify clientOrderLineId to point out the correct article to be used.
When ordering an article that is a bundle containing several individual articles and the Service Provider cannot assign users to the bundle article directly, then the Service Provider returns one order line per included item (each referencing the same orderLineId) which is then used by the client to assign licenses.
If bundles are "unpacked" (meaning that the items contained by the bundle are ordered individually) before ordering a bundle article, digital or hybrid - then the containing bundle article can be referenced through the field "bundleArticleNumber".
Date is sent in the format ISO 8601 (YYYY-MM-DD), e.g. "2022-01-03".
Possible values for data with type code are specified here. All values are non case sensitive.
Used in:
- /v1/orders/create Request
Value | Description |
---|---|
organization | Buyer is an organization. |
private | Private buyer. |
Used in:
- /v1/orders/create Request
Value | Description |
---|---|
skolverket | School unit code from Skolverket. |
client | Id specified by the client. |
serviceProvider | Id specified by the service provider. |
other | Value agreed by the client and the service provider. |
Used in:
- /v1/orders/create Response
- /v1/orders/create Response to an asynchronous response
Value | Description |
---|---|
beingProcessed | The order is handled by the service provider. If the service provider responds with this status, the client expects to receive another call to the responseUrl at a later time. Can be followed by backordered, delivered, failed |
backordered | Backordered, the service provider can send with an expected delivery date in deliveryDate. In the same way as in beingProcessed, the client expects to receive a call to responseUrl. Can be followed by delivered, failed |
delivered | The order is delivered and the retailer can find the license keys that can be used for the assignment in licenseKeys. |
failed | Failed, order has not gone through. The service provider can send more detailed information in the errorMessage. |
Used in:
- /v1/assignments/create Request
- /v1/assignments/create Response
- /v1/users/licenses
Value | Description |
---|---|
client | Id specified by the client. |
serviceProvider | Id specified by the service provider. |
eppn | eduPersonPrincipalName. |
egil | EGIL-klientens SCIM-id. |
ss12000 | SS12000 uuid. |
Google-id. | |
microsoft | Microsoft-id. |
Email address. | |
other | Other type of id. |
Used in:
- /v1/assignments/create Request
Value | Description |
---|---|
client | Id specified by the client. |
serviceProvider | Id specified by the service provider. |
egil | EGIL-klientens SCIM-id. |
ss12000 | SS12000 uuid. |
Google-id. | |
microsoft | Microsoft-id. |
other | Other type of id. |
Used in:
- /v1/assignments/create Response
- /v1/assignments/delete Response
Value | Description |
---|---|
beingProcessed | The assignment is handled by the service provider. If the service provider responds with this status, the client expects to receive another call to the responseUrl at a later time. |
assigned | The assignment is complete and the license is ready to use. |
unassigned | The unassignment request succeeded and the user no longer has the license. |
failed | The assignment or unassignment has not gone through. The service provider can send more detailed information in the errorMessage. |