Unicat API Reference

Up - API Reference - Home


Bulk operations

The selection parameter

Bulk requests operate on a potentially large selection of items, be they records, assets, or schema items.

The selection parameter is used to identify the items that are affected by the operation. This can be a simple list of gids, the children of an item, the results of a query, or any combination of the three.

Let's have a look at each in turn.

In the simplest form, you just provide a list of gids to work with.

POST /api/p/<project gid>/records/bulk/delete
Authorization: Bearer <JWT>

{
    "selection": ["<gid-1>", "<gid-2>", "<gid-3>"],
    
}

For working with children, you provide a children object that specifies the parent gid. If needed, you can exclude a list of child gids from the results. For records, an additional channel and/or ordering parameter can be included in the object. Schema items don't support the children selection type.

POST /api/p/<project gid>/records/bulk/delete
Authorization: Bearer <JWT>

{
    "selection": [
        {
            "children": "<gid-9>",
            "exclude": ["<gid-x>", "<gid-y>", "<gid-z>"],
        }
    ],
    
}

Note that the selection parameter itself is still a list - that fact is used when we combine multiple selection types.

A powerful option is the ability to work on the results of a query. You provide a search object that matches the parameters you would use in a regular search. Again, you can exclude a list of gids from the results.

POST /api/p/<project gid>/records/bulk/delete
Authorization: Bearer <JWT>

{
    "selection": [
        {
            "search": {
                "language": "nl",
                "q": "+cms 225",
                "filter": ["definition", "is", "<definition-gid>"],
            },
            "exclude": ["<gid-a>", "<gid-b>", "<gid-c>"]
        },
    ],
    
}

Finally, you can combine all these in a single request.

POST /api/p/<project gid>/records/bulk/delete
Authorization: Bearer <JWT>

{
    "selection": [
        "<gid-1>",
        "<gid-2>",
        "<gid-3>",
        {
            "children": "<gid-9>",
            "exclude": ["<gid-x>", "<gid-y>", "<gid-z>"],
        },
        "<gid-4>",
        "<gid-5>",
        {
            "search": {
                "language": "nl",
                "q": "+cms 225",
                "filter": ["definition", "is", "<definition-gid>"],
            },
            "exclude": ["<gid-a>", "<gid-b>", "<gid-c>"]
        },
        {
            "children": "<gid-o>",
        },
    ],
    
}

The response

For many bulk operations, we don't report on individual items, because that report can potentially be very large, or it is processed in the background. We return a job.token, and you can look for it when you handle sync information - we report on the job while it is running and post a completion status there as soon as the operation is done.

Authorization: <JWT>

{
    "success": true,
    "result": {
        "job.token": "7c136ddb-4dfa-4ec1-bad4-15067cbf80d9",
    },
    "data": {}
}

The job report has a simple progress structure, found in the data attribute for a sync item. The job status can be 'queued', 'rejected', 'processing', or 'done'; additional information about the job can be found in info and is job-dependent. If the status is 'rejected', then info will hold an 'error' attribute.

{
    "type": "cc",
    "cursor": <cursor>,
    "action": "UPDATE",
    "data_type": "jobs",
    "data_key": "7c136ddb-4dfa-4ec1-bad4-15067cbf80d9",
    "data": {
        "project_gid": "<project_gid-or-null>",
        "job": "bulk_delete_records",
        "status": "processing",
        "info": {
            "total": 120,
            "remaining": 26
        },
        "created_on": 1613565541.4195538,
        "updated_on": 1613565543.2836412,
    }
}

We also support bulk get operations to work with selections. That way, many reports can be generated relatively easily using the API. For these operations, we return a page.cursor that you must use for enumeration. For the initial call, you don't have to specify a cursor, you just set the page size. For subsequent calls, you must include the page.cursor received from each previous call, until it is null, then enumeration is complete. All other parameters stay the same in subsequent requests.

First request/response:

POST /api/p/<project gid>/records/bulk/get
Authorization: Bearer <JWT>

{
    "language": "nl",
    "selection": [
        {
            "search": {
                "language": "nl",
                "q": "+cms 225",
            },
        },
    ],
    "page.size": 10,
}
Authorization: <JWT>

{
    "success": true,
    "result": {
        "records": ["96ec02b2-fb8d-4fb4-b952-fad0c4b88a74", ],
        "records.size": 17,
        "page.cursor": <the-first-cursor-value>
    },
    "data": {
        "records": {
            "96ec02b2-fb8d-4fb4-b952-fad0c4b88a74": {
                
            },
            
        }
    }
}

To get the remaining 7 results, provide the returned page.cursor in the next request.

POST /api/p/<project gid>/records/bulk/get
Authorization: Bearer <JWT>

{
    "language": "nl",
    "selection": [
        {
            "search": {
                "language": "nl",
                "q": "+cms 225",
            },
        },
    ],
    "page.cursor": <the-first-cursor-value>,
    "page.size": 10,
}
Authorization: <JWT>

{
    "success": true,
    "result": {
        "records": ["10886fb0-5cc9-43b4-8d3d-8de601f14423", ],
        "records.size": 17,
        "page.cursor": null
    },
    "data": {
        "records": {
            "10886fb0-5cc9-43b4-8d3d-8de601f14423": {
                
            },
            
        }
    }
}

The response now has null for the page.cursor, so we know we are done. A cursor value is a tuple with selection index and some additional cursor value, which can be None, an integer, or a string, depending on selection type. You don't need to know this, you just need to use it as it was given.