REST API

AtroCore is an API-centric application, so a frontend uses REST API to connect with a backend. Our REST API is based on OpenAPI (Swagger), so you can generate your client automatically.

All operations you perform using UI can be performed via API requests using the programing language of your choice. You can learn how API works if you trace what's going in the network tab in your browser console (press F12 key to open the console).

All requests needs to have the header: Content-Type: application/json.

The path to the API in AtroCore is: /api/v1/. Only this path can be used for your API requests.

We recommend to create a separate API user with specific rights (configure and assign a role to him) and use this user for API calls.

Video Tutorials

API Documentation

REST API documentation is generated for each project automatically, based on your configurations and modules you are using. To access it please go to https://address_of_your_atrocore/apidocs/.

For example the REST API documentation for our public demo instance (demo.atropim.com) is available here: https://demo.atropim.com/apidocs/

1. Step: Authentication

To be able to use AtroCore API you need to go through authentication and obtain access token. Please watch the video tutorial to learn how to authorize in the REST API.

For obtaining access token you need to send GET request to /api/v1/App/user using Basic Authentication.

2. Step: Making requests

To see which requests are available read the documentation for your AtroCore instance.

To access it please go to https://address_of_your_atrocore/apidocs/.

Example of GET API request:

GET https://address_of_your_atrocore/api/v1/Product/2d643ca0gff7rh7c6

Additional API specifications

Here you can find explonations for several not standart requests

Bulk Create and Bulk Update

To do bulk create and bulk update, you can use the request

POST https://address_of_your_atrocore/api/v1/MassActions/action/upsert

The system will try to find existing entities based on the identifier or unique fields. If an entity is found, it will be updated, otherwise it will be created by the system.

Example of Payload:

[
    {
        "entity": "Product",
        "payload": {
            "name": "Apple iPhone 15",
            "sku": "iphone15"
        }
    },
    {
        "entity": "Product",
        "payload": {
            "id: "2348924928743",
            "name": "Apple iPhone 15 Pro Max",
        }
    }
]

You can see more detail about this api on https://address_of_your_atrocore/apidocs/ in section "MassActions"

File Upload

There are several posibilities to upload file to AtroCore. In any case for all types you need to create File Entity, but using different input data.

1) Upload by file content:

Request URL: https://YOUR-PIM-DOMAIN/api/v1/File

Request Method: POST

Request Headers:

Content-Type: application/json
Authorization-Token: YOUR-AUTH-TOKEN

Request body:

{
  "id": "a99060ec2fc0ddad2",
  "name": "Test1.txt",
  "storageId": "c6628d813e33f2eea",
  "fileContents": "data:text/plain;base64,MTEx"
}
  • id - file ID. Not required for uploading by content
  • name - file name. Required
  • storageId - File Storage ID. Required
  • fileContents - prepared file content data. The mask: "data:{{mimeType}};base64,{{base64EncodedContent}}". In our example file content is "111" that's why there is "MTEx" in request.

2) Upload by file URL:

Request URL: https://YOUR-PIM-DOMAIN/api/v1/File

Request Method: POST

Request Headers:

Content-Type: application/json
Authorization-Token: YOUR-AUTH-TOKEN

Request body:

{
  "id": "a99060ec2fc0dda33",
  "name": "customer-benefits3.jpg",
  "storageId": "c6628d813e33f2eea",
  "url": "https://www.atrocore.com/user/env/www.atrocore.com/pages/about-us/04._project-management/customer-benefits3.jpg"
} 
  • id - file ID. Not required for uploading by URL
  • name - file name. Required
  • storageId - File Storage ID. Required
  • url - URL of the file to be uploaded

3) Upload by file chunks. For a large files

Upload by chunks is more complex then simple upload. You need to split the original file into the pieces, then send the pieces via API. You can send the pieces asynchronously.

Request URL: https://YOUR-PIM-DOMAIN/api/v1/File

Request Method: POST

Request Headers:

Content-Type: application/json
Authorization-Token: YOUR-AUTH-TOKEN

Request body:

{
  "id": "a99060ec2fc0dda33",
  "name": "some.pdf",
  "storageId": "c6628d813e33f2eea",
  "fileUniqueHash": "22551854",
  "start": 0,
  "piece": "data:application/octet-stream;base64,I4hYADzRed08...",
  "piecesCount": 2  
} 
  • id - file ID. Required
  • name - file name. Required
  • storageId - File Storage ID. Required
  • fileUniqueHash - Unique file ID. Not the same as File Entity ID. Required
  • start - The start of the piece(slice). Required
  • piece - prepared file slice content data. Required
  • piecesCount - The number of file pieces. Required

In response you will see:

{
    "chunks": [
        "0",
        "2097152",
        "4194304",
        "6291456",
        ...
    ]
}

it means that the piece has been uploaded succesfully, but not all pieces are uploaded.

{
    "id": "acd7de2808e90041c",
    "name": "test.pdf",
    "chunks": [
        "0",
        "2097152",
        "4194304",
        "6291456",
        ...
    ]
}

it means that the piece has been uploaded succesfully and it was the last one. File has been created.

Here is an example how to split file on JS:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>File upload example</title>
</head>
<body>
<h1>File upload example</h1>
<input type="file" id="fileInput">
<button onclick="upload()">Upload</button>
</body>
</html>

<script type="text/javascript">
    function slice(file, start, end) {
        let slice = file.mozSlice ? file.mozSlice : file.webkitSlice ? file.webkitSlice : file.slice ? file.slice : noop;
        return slice.bind(file)(start, end);
    }

    function createFilePieces(file, sliceSize, start, pieces) {
        let end = start + sliceSize;

        if (file.size - end < 0) {
            end = file.size;
        }

        pieces.push({start: start, piece: slice(file, start, end)});

        if (end < file.size) {
            start += sliceSize;
            createFilePieces(file, sliceSize, start, pieces);
        }
    }

    function upload() {
        const files = document.getElementById('fileInput').files;
        if (!files[0]) {
            alert('Please, select the file.');
            return;
        }

        const inputFile = files[0];
        const chunkSize = 2 * 1024 * 1024; // 2Mb

        const pieces = [];
        createFilePieces(inputFile, chunkSize, 0, pieces);

        const piecesCount = pieces.length;

        if (piecesCount < 2) {
            alert('File is too small.');
            return;
        }

        pieces.forEach(item => {
            const reader = new FileReader();
            reader.readAsDataURL(item.piece);
            reader.onloadend = () => {
                let row = {
                    start: item.start,
                    piece: reader.result,
                    piecesCount: piecesCount
                };
                console.log(row) // show the result row in browser console
            };
        });
    }
</script>