1. WebAPI features
EDU WebAPI allows you to:
- Check current stock with client specific discounted prices
- Place order on selected titles
- Choose your delivery address
After completing an order a client will receive a digital invoice sent to the email address selected while placing the order.
EDU WebAPI was created by following REST standard which provides easy access to API methods.
Authorization system is based on OAuth2.0 model meaning every API request requires a user to add temporary a token to each of the requests.
The token lifetime is set to 1 hour.
Placing an order (https://api.eduksiazka.pl/api/Order) should end up with the following result:
{
"Status": "OK",
"StatusDetails": [
{
"HttpStatusCode": 201,
"Opis": "Utworzono wpis o numerze: 12345, nr wew.: test0001",
"Message": "Created entry with id: 12345, client's id: test00001"
}
],
"ItemsErrors": []
}
Attention:
While contacting our sales department please use your order_id. It will speed up the process of finding your order in our system.
{
...
order_id:"20145264"
...
}
2. Methods available in Web API
-
token – generates token required to make API requests
(AccessToken)
-
URL address:
https://api.eduksiazka.pl/api/token
- HTTP Method: POST
-
Required data: UserName, Password, grant_type
- Return data type: JSON
- Token lifetime: 1 hour
Sample code in C#:
string username = "MY_USERNAME";
string password = "MY_PASSWORD";
var client = new RestClient("https://api.eduksiazka.pl/api/token"); //Setting URL Address
var request = new RestRequest(Method.POST); //Setting HTTP Method
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", string.Format("grant_type=password&username={0}&password={1}", username, password), ParameterType.RequestBody);
var queryResult = client.Execute <List<RestRequest>>(request);
dynamic obj = JsonConvert.DeserializeObject<dynamic>(queryResult.Content);
JObject parsed = JObject.Parse(queryResult.Content);
foreach (var pair in parsed)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}
Example of response:
{
"access_token": "8P4KhaVTH...",
"token_type": "bearer",
"expires_in": 3599
}
-
GetDeliveryAddresses – returns available delivery addresses
-
URL address:
https://api.eduksiazka.pl/api/PH/GetDeliveryAddresses
- HTTP Method: GET
- Required data: ACCESS_TOKEN
- Return data type: JSON
Sample code in C#:
string ACCESS_TOKEN = "8P4KhaVTH...";
client = new RestClient("https://api.eduksiazka.pl/api/PH/GetDeliveryAddresses");
request = new RestRequest(Method.GET);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", string.Format("Bearer {0}", ACCESS_TOKEN));
queryResult = client.Execute<List<RestRequest>>(request);
obj = JsonConvert.DeserializeObject<dynamic>(queryResult.Content);
parsed = JObject.Parse(queryResult.Content);
foreach (var pair in parsed)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}
Example of response:
{
"Table": [
{
"CardCode": "O123456",
"SystemName": "Edu Błonie",
"Address": "Pass 20L magazyn nr 7 05-870 Błonie"
},
{
"CardCode": "O123456",
"SystemName": "Edu H.Lublin",
"Address": "Rapackiego 25 20-150 Lublin"
}
]
}
Attention:
Please pay attention to
SystemName values which are used as delivery addresses when placing a new order.
-
GetStock2 – returns information about the stock
-
URL address:
https://api.eduksiazka.pl/api/products/GetStock2
- HTTP Method: GET
- Required data: ACCESS_TOKEN
- Return data type: JSON
- Optional parameter dateFrom which allows user to get updated data from selected DateTime.
Parameter should be added in form of Querystring i.e. https://api.eduksiazka.pl/api/products/GetStock2?dateFrom=2020-06-01 12:00:00
Sample code in C#:
string ACCESS_TOKEN = "8P4KhaVTH...";
client = new RestClient("https://api.eduksiazka.pl/api/products/GetStock2");
request = new RestRequest(Method.GET);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", string.Format("Bearer {0}", ACCESS_TOKEN));
queryResult = client.Execute<List<RestRequest>>(request);
obj = JsonConvert.DeserializeObject<dynamic>(queryResult.Content);
parsed = JObject.Parse(queryResult.Content);
foreach (var pair in parsed)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}
Example of response (fragment):
{
"Table":
[
{
"ItemCode": "0000000000644",
"Blonie": 5,
"Kielce": 0,
"Krakow": 2,
"Lublin": 1
},
...
{
"ItemCode": "0000000006448",
"Blonie": 100,
"Kielce": 3,
"Krakow": 0,
"Lublin": 3
}
]
}
- GetProductsInfo – returns information about products
-
URL address:
https://api.eduksiazka.pl/api/products/GetProductsInfo
- HTTP Method: GET
- Required data: ACCESS_TOKEN
- Return data type: JSON
- Optional parameter dateFrom which allows user to get updated data from selected DateTime.
Parameter should be added in form of Querystring i.e. https://api.eduksiazka.pl/api/products/GetStock?dateFrom=2020-06-01 12:00:00
Sample code in C#:
string ACCESS_TOKEN = "8P4KhaVTH...";
client = new RestClient("https://api.eduksiazka.pl/api/products/GetProductsInfo");
request = new RestRequest(Method.GET);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", string.Format("Bearer {0}", ACCESS_TOKEN));
queryResult = client.Execute<List<RestRequest>>(request);
obj = JsonConvert.DeserializeObject<dynamic>(queryResult.Content);
parsed = JObject.Parse(queryResult.Content);
foreach (var pair in parsed)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}
Example of response (fragment):
{
"Table":
[
{
"ItemCode": "0000000000644",
"ItemName": "Nicholas's little starters Level 1 CD audio",
"Status": "Aktywne",
"Publisher": "Wydawnictwo Szkolne PWN",
"NetPrice": "34.150000",
"VAT": "23",
"NetPriceAfDisc": "26.30",
"FullDescription": "",
"Author": "",
"Format": "",
"Binding": "Inna",
"Image": "",
"Publishment_Year": "2017",
"Level": "Przedszkola",
"Subject": "Język angielski",
"Category": "Nie dotyczy"
},
...
{
"ItemCode": "0000000006448",
"ItemName": "Nicholas's little starters Level 3 CD audio",
"Status": "Schodzące",
"Publisher": "Wydawnictwo Szkolne PWN",
"NetPrice": "34.150000",
"VAT": "23",
"NetPriceAfDisc": "26.30",
"FullDescription": "",
"Author": "",
"Format": "",
"Binding": "Inna",
"Image": "",
"Publishment_Year": "2017",
"Level": "Nie dotyczy",
"Subject": "Język angielski",
"Category": "CD/DVD/MP3"
}
]
}
- Invoices – allows user to get invoice in selected file format. Invoices cannot be older than form last 3 months
-
URL address:
https://api.eduksiazka.pl/api/Invoices
- HTTP Method: GET
- Required data: ACCESS_TOKEN
- Return data type: JSON, XML or PDF(bytes)
- Optional parameters:
- format - allows user to choose between values: JSON(default), XML or PDF
- number - allows user to select invoice with given number. Parameter will only work if parameter onlyNew is set to false
- onlyNew - allows user to get only new invoices. Method will return only invoices which hasn't been returned using this method before(with onlyNew=true). Method will also not work for PDF format
- Samples of use: https://api.eduksiazka.pl/api/Invoices?format=XML&number=20xxxxxxxx or https://api.eduksiazka.pl/api/Invoices?format=XML&onlyNew=true
Sample code in C#:
string ACCESS_TOKEN = "8P4KhaVTH...";
client = new RestClient("https://api.eduksiazka.pl/api/Invoices?format=JSON&number=1807102370");
request = new RestRequest(Method.GET);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", string.Format("Bearer {0}", ACCESS_TOKEN));
queryResult = client.Execute<List<RestRequest>>(request);
obj = JsonConvert.DeserializeObject<dynamic>(queryResult.Content);
parsed = JObject.Parse(queryResult.Content);
foreach (var pair in parsed)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}
Sample of response as JSON:
[
{
"Document-Invoice": {
"Invoice-Header": {
"InvoiceNumber": "1807102370",
"InvoiceDate": "2018-07-25T00:00:00",
"SalesDate": "2018-07-25T00:00:00",
"InvoiceCurrency": "PLN",
"InvoicePaymentDueDate": "2018-08-08T00:00:00",
"InvoicePostDate": "2018-07-25T00:00:00",
"InvoiceComments": "0"
},
"Invoice-Parties": {
"Buyer": {
"TaxID": "",
"Name": "Firma 1",
"StreetAndNumber": "Rolna 8",
"CityName": "Kielce",
"PostalCode": "25-419",
"Country": "PL"
},
"Shipment": {
"Name": "Kielce",
"SteetAndNumber": "Rolna 8",
"CityName": "Kielce",
"PostalCode": "25-419",
"Country": "PL"
},
"Seller": {
"ILN": "PL5272523217",
"TaxID": "PL5272523217",
"AccountNumber": "",
"Name": "EDU-KSIĄŻKA Sp. z o.o.",
"StreetAndNumber": "Kolejowa 5/7",
"CityName": "Warszawa",
"PostalCode": "01-217",
"Country": "PL"
}
},
"Invoice-Lines": [
{
"LineItem": {
"LineNumber": "1",
"EAN": "9788361243021",
"BuyerItemCode": "",
"SupplierItemCode": "9788361243021",
"ItemDescription": "Sky High PL 1 SB + CD-ROM",
"InvoiceQuantity": 1,
"UnitOfMeasure": "",
"InvoiceUnityNetPrice": 51.33,
"InvoiceUnitNetPriceAfDisc": 51.33,
"InvoiceUnitGrossPrice": 53.90,
"TaxRate": 5.0,
"TaxCategoryCode": "F05",
"TaxReference": {
"ReferenceType": "PKWiU",
"ReferenceNumber": ""
},
"TaxAmount": 2.57,
"NetAmount": 51.33
}
}
],
"Invoice-Summary": {
"TotalLines": 1,
"TotalNetAmount": 51.33,
"TotalTaxableBasis": 51.33,
"TotalTaxAmount": 2.57,
"TotalGrossAmount": 53.90,
"TaxSummary": [
{
"TaxSummaryLine": {
"TaxRate": 5.0,
"TaxCategoryCode": "F05",
"TaxAmount": 2.57,
"TaxableBasis": 51.33,
"TaxableAmount": 51.33,
"GrossAmount": 53.90
}
}
]
}
}
}
]
Sample of response as XML
sample
- Order – allows a user to place a new order
-
URL address:
https://api.eduksiazka.pl/api/Order
- HTTP Method: POST
- Required data: order, c_ETB_MG2_ORDERLINE
- Return data type: JSON
|
Object order
|
| # |
Field name |
Data type |
Required |
Description |
| 1 |
order_id |
String |
YES |
Client's order ID. Value cannot be longer than 20 characters |
| 2 |
order_address_nazwa |
String |
YES |
Sytem name of delivery address. Value can be acquired from GetDeliveryAddresses method, field SystemName.
|
| 3 |
order_comments |
String |
NO |
Optional comment added to an order |
| 4 |
order_email |
String |
YES |
The email address where we should send your invoice |
| 5 |
order_magazyn |
String |
NO |
Warehouse from which your items are ordered. Currently avaialable values are: 01 (default value), 04, 06, 07.
Below short description for each value which is linked with data you are receiving from GetStock method:
- 01 - Blonie
- 04 - Kielce
- 06 - Krakow
- 07 - Lublin
|
| 6 |
order_partialDelivery |
Boolean |
NO |
By default it is set as False. If set as True allows you to place an order even if the items are not in stock. It also means that you may not receive the items that are unavailable at the moment |
| 7 |
c_ETB_MG2_ORDERLINE |
Array |
YES |
Ordered items |
|
Object c_ETB_MG2_ORDERLINE
|
| # |
Field name |
Data type |
Required |
Description |
| 1 |
orderline_itemcode |
String |
YES |
ISBN of the ordered item |
| 2 |
orderline_quantity |
Integer |
YES |
Quantity of the ordered item (Value has to be greater than 0)
|
Sample code in C#:
string ACCESS_TOKEN = "8P4KhaVTH...";
client = new RestClient("https://api.eduksiazka.pl/api/Order");
request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", string.Format("Bearer {0}", ACCESS_TOKEN));
dynamic jOrder = new JObject();
jOrder.order_id = "test0001";
jOrder.order_comments = "Test comment";
jOrder.order_address_nazwa = "Edu H.Lublin";
jOrder.order_email = "address@pl";
jOrder.c_ETB_MG2_ORDERLINE = new JArray() as dynamic;
dynamic jOrderLine = new JObject();
jOrderLine.orderline_itemcode = "0000000000644";
jOrderLine.orderline_quantity = 3;
jOrder.c_ETB_MG2_ORDERLINE.Add(jOrderLine);
jOrderLine = new JObject();
jOrderLine.orderline_itemcode = "00000000006448";
jOrderLine.orderline_quantity = 10;
jOrder.c_ETB_MG2_ORDERLINE.Add(jOrderLine);
request.AddJsonBody(jOrder.ToString());
queryResult = client.Execute<List<RestRequest>>(request);
obj = JsonConvert.DeserializeObject<dynamic>(queryResult.Content);
parsed = JObject.Parse(jOrder.ToString());
foreach (var pair in parsed)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}
var status = JObject.Parse(queryResult.Content);
Console.WriteLine("\nAPI response: ");
foreach (var pair in status)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}
Console.ReadKey();
If method was called successfuly you will receive following response from the server:
{
"Status": "OK",
"StatusDetails": [
{
"HttpStatusCode": 201,
"Opis": "Utworzono wpis o numerze: 12345, nr wew.: test0001",
"Message": "Created entry with id: 12345, client's id: test00001"
}
],
"ItemsErrors": []
}
3. Errors
Most of the errors from API has the form of the following JSON structure:
- Status - status of the response message could be OK, WARNING or ERROR
-
StatusDetails (array) - there you can find more details about the status you received
- HttpStatusCode - as the name suggests its code of Http Response
- Opis - polish version of the message
- Message - english version of the message
-
ItemsErrors (array) - if there are errors/warnings caused by items you can find more details here
- orderline_itemcode - ISBN of ordered item
- Opis - polish version of the message
- Message - english version of the message
Below you can see the visualization of the structure:
{
"Status": "ERROR",
"StatusDetails": [
{
"HttpStatusCode": "code",
"Opis": "Message in Polish",
"Message": "Message in English"
},
...
],
"ItemsErrors": [
{
"orderline_itemcode": "ISBN",
"Opis": "Message in Polish",
"Message": "Message in English",
},
...
]
}
| # |
Error |
HTTP code |
Description |
| 1 |
Page not found
|
404 |
The address has not been found. Check if the address you have entered is correct
|
| 2 |
Access is denied
|
401 |
The token value is invalid or the token has expired.
|
| 3 |
Data you provided are incorrect
|
400 |
Access data are invalid. (UserName and/or Password)
|
| 4 |
SSL is required! Try using links with HTTPS |
403 |
You are trying to use HTTP protocol. Please check your links and use HTTPS which is required |
| 5 |
Access to API has expired. Please contact person responsible for granting you access |
400 |
API access has expired. Please contact the person responsible for granting you the access |
| 6 |
Create error - no items in order |
406 |
There are no items added to the order |
| 7 |
orderline_itemcode value cannot be empty |
406 |
ISBN value of the item was not supplied |
| 8 |
orderline_quantity value cannot be empty |
406 |
The quantity value of item was not supplied |
| 9 |
orderline_quantity value must be greater than zero |
406 |
The quantity of the ordered item has to be greater than 0 |
| 10 |
Error for selected items occured. Check details in ItemsErrors[] section |
406 |
An error has occured for selected items which is most commonly caused by the item being out of stock. Please, check the ItemsErrors[] section for more information. |
| 11 |
order_address_nazwa value cannot be empty |
406 |
SystemName value of the item was not supplied |
| 12 |
order_id value cannot be empty |
406 |
order_id value of the item was not supplied |
| 13 |
order_email value cannot be empty |
406 |
order_email value of the item was not supplied |
| 14 |
order_magazyn value cannot be empty |
406 |
order_magazyn value was set to empty string or null |
| 15 |
Selected warehouse (order_magazyn) is not available |
406 |
You don't have permissions to place orders from this warehouse |
| 16 |
All items are unavailable |
406 |
All items you have entered in your order are unavailable. Check list of available items in GetStock method |
| 17 |
Item unavailable |
406 |
Item is unavailable. Check list of available items in GetStock method |
| 18 |
Your JSON data format is invalid |
400 |
Your JSON structure is invalid |
| 19 |
Format of dateFrom parameter is incorrect |
406 |
Date format of dateFrom parameter is invalid.
Date should be in following format: YYYY-MM-dd hh:mm:ss, where:
- YYYY - year i.e. 2020;
- MM - month (01-12);
- dd - day (01-31 which may be different considering month);
- hh - hours in 24h format;
- mm - minutes (01-59);
- ss - seconds (01-59);
|
| 20 |
order_id length has to be no longer than 20 characters |
406 |
order_id value cannot be longer than 20 characters |