Migrating from Taskrunner to the EntryScape API¶
The Taskrunner API is deprecated. Everything it offered, adding and replacing distribution files and following the resulting job, is available in the EntryScape API, together with SDKs for Python, JavaScript, TypeScript and C# and an MCP server for AI assistants. This page describes how to move an existing Taskrunner integration over. New to the API altogether? Start with EntryScape API: getting started.
Taskrunner keeps working during a transition period. A removal date will be announced on this page and on the Taskrunner overview.
Which host to use
Taskrunner was reached under your EntryScape installation, for example https://demo.entryscape.com/taskrunner/v1/. The EntryScape API runs on its own host, which MetaSolutions provides for your installation. The examples below write it as $API. The interactive reference at entryscape.org/api documents every operation and links to the SDK downloads.
What changes¶
| Taskrunner | EntryScape API | |
|---|---|---|
| Base URL | https://<installation>/taskrunner/v1 |
$API (provided per installation) |
| Authentication | Cookie: auth_token=... obtained from EntryStore auth/cookie |
X-Auth-Token: ... header, token obtained from POST $API/auth/login |
| Replace a file | POST /distribution/replaceFile?resourceURI=<file> |
POST /distribution/replaceFile?resourceURI=<file> |
| Add a file | POST /distribution/addFile?resourceURI=<distribution> |
POST /distribution/addFile?resourceURI=<distribution> |
| Job status | GET /job/{jobId}, no authentication |
GET /job/{jobId}, authentication required |
| Response on accepted upload | 200 with jobId (and prototypeURI for add) |
202 with jobId, status and message; the new file's URI arrives as resultUrl on the finished job |
| Job id | small integer | 64-bit integer, for example 1787937550074240 |
| Status values | Pending, Processing, Success, Failed, Not found |
PENDING, PROCESSING, SUCCESS, FAILED; an unknown or expired job is a 404 |
| Connected API distribution | Refreshed automatically after the job | Refreshed automatically after the job |
| Wrong kind of URI | Job fails | 422 before anything is queued; a URI that resolves to nothing is 404 |
The query parameter is still called resourceURI, it means the same thing for each operation (the distribution for add, the file for replace), and the multipart field is still called file, so the upload request itself changes very little. The differences that need attention are authentication and the job status handling.
Step 1: Authenticate¶
Taskrunner reused the EntryStore cookie and required you to strip its Path=/store/ attribute. The EntryScape API has its own login, and the token goes in a header, so there is no cookie to handle.
API=https://<your EntryScape API host>
TOKEN=$(curl -sS -X POST "$API/auth/login" \
-H 'Content-Type: application/json' \
--data '{"username": "example@metasolutions.se", "password": "***"}' \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["auth_token"])')
The response body carries auth_token, user and, when the store reports it, expires. Add "max_age_seconds": 604800 to the login body to ask for a longer-lived session. Verify the session with:
curl -sS "$API/auth/whoami" -H "X-Auth-Token: $TOKEN"
{"user":"example@metasolutions.se","authenticated":true} means the token is live. {"user":"guest","authenticated":false} means the token is missing, expired, or belongs to a different EntryStore instance than the API is configured for.
Two things to know when scripting this:
- The login endpoint is rate limited. A script that retries a wrong password will start receiving
429. POST $API/auth/logoutinvalidates the token on the server. Do not call it on a token you intend to reuse.
Send the token as the X-Auth-Token header on every request below. Only browser clients that rely on the auth_token cookie instead need the additional CSRF header described in the API reference; scripts using the header need nothing more.
Step 2: Replace a file¶
This is the same request as before with a different base URL and a different authentication header. The resourceURI is still the resource URI of the file to replace, found in EntryScape Catalog under the distribution's information icon as "web address for access" (see detailed information).
Taskrunner:
curl --location --request POST \
'https://demo.entryscape.com/taskrunner/v1/distribution/replaceFile?resourceURI=https://demo.entryscape.com/store/34/resource/5' \
--header 'Cookie: auth_token=***' \
--form 'file=@"/home/example.csv"'
EntryScape API:
curl -sS -X POST \
"$API/distribution/replaceFile?resourceURI=https://demo.entryscape.com/store/34/resource/5" \
-H "X-Auth-Token: $TOKEN" \
-F 'file=@/home/example.csv'
The upload is accepted with 202 Accepted instead of 200, and the body now carries the initial status:
{"jobId": 1787937550074240, "status": "PENDING", "message": "File replacement queued for processing"}
Store jobId as a 64-bit integer or a string. It no longer fits in a 32-bit field.
Requests that Taskrunner accepted and the EntryScape API rejects:
| Situation | Response |
|---|---|
| No or expired token | 403 (an anonymous session is a read-only guest) |
| File larger than the configured limit (50 MB by default) | 413 |
| Filename containing a path separator, or longer than 200 characters | 400 |
File content that does not match the file extension (for example a ZIP named .csv) |
Accepted with 202, then the job ends FAILED with the error "File content does not match declared type" |
Step 3: Add a new file¶
This is also the same request with a different base URL and header. As with Taskrunner, resourceURI is the resource URI of the distribution, found under the distribution's information icon in the "About" tab as "Resource". The job creates a new file entry in the distribution, stores the upload in it, links it from the distribution and updates the distribution's modification date.
curl -sS -X POST \
"$API/distribution/addFile?resourceURI=https://demo.entryscape.com/store/34/resource/5" \
-H "X-Auth-Token: $TOKEN" \
-F 'file=@/home/example.csv'
Taskrunner answered an add with a prototypeURI, the address the file would get. The EntryScape API reports the file's address when the job has finished, as resultUrl on the job status (see step 4). Store it: it is the resourceURI for every later replaceFile of that file.
Passing a file URI to addFile, or a distribution URI to replaceFile, is answered with 422 and a message saying which kind of entry was found, before anything is queued. Taskrunner accepted the request and failed the job later.
Step 4: Check the job¶
The status endpoint has the same shape, but it now requires the same X-Auth-Token header as the upload. Taskrunner allowed anonymous status checks.
curl -sS "$API/job/1787937550074240" -H "X-Auth-Token: $TOKEN"
{
"jobId": 1787937550074240,
"status": "SUCCESS",
"jobType": "REPLACE",
"resourceURI": "https://demo.entryscape.com/store/34/resource/5",
"resultUrl": "https://demo.entryscape.com/store/34/resource/5",
"filename": "example.csv",
"user": "example@metasolutions.se",
"received": "2026-09-08T10:00:00.000Z",
"terminated": "2026-09-08T10:00:05.123Z"
}
Map the status values as follows and update any code that compared against the old mixed-case strings:
| Taskrunner | EntryScape API | Extra fields |
|---|---|---|
Pending |
PENDING |
queuePosition |
Processing |
PROCESSING |
progress (for jobs that report it) |
Success |
SUCCESS |
terminated, resultUrl (the file's resource URI) |
Failed |
FAILED |
terminated, error |
Not found |
HTTP 404 |
Poll every couple of seconds. Jobs are kept for a limited time after they finish (24 hours by default), after which the status endpoint returns 404, so record the outcome when you see it rather than looking it up later.
Connected API distributions¶
As with Taskrunner, a distribution with an auto-generated API (see Create an API using tabular data) has its API refreshed as part of the job: an added file's rows are appended to the API, and a replaced file causes the API to be rebuilt from all the distribution's files. The API distribution's modification date is updated when that is done.
Also as with Taskrunner, such a distribution only accepts CSV files. Uploading anything else to it fails the job with the error "File content must be CSV" before any change is made. The job stays in PROCESSING while the API is being rebuilt, which can take a while for large files, so allow for that when you poll.
Using an SDK instead of curl¶
The generated SDKs wrap the three operations, including the polling loop. The Python SDK, for example:
import asyncio
import entryscape
from entryscape.models import JobStatusValue
async def replace(path, resource_uri, token):
configuration = entryscape.Configuration(host="https://<your EntryScape API host>")
configuration.api_key["auth_header"] = token
async with entryscape.ApiClient(configuration) as client:
upload_api = entryscape.UploadApi(client)
job_api = entryscape.JobApi(client)
with open(path, "rb") as f:
job = await upload_api.replace_file_in_distribution(
resource_uri=resource_uri, file=(path, f.read())
)
while True:
await asyncio.sleep(2)
status = await job_api.get_job_status(job.job_id)
if status.status == JobStatusValue.Success:
return status
if status.status == JobStatusValue.Failed:
raise RuntimeError(status.error)
The SDK downloads, a complete file-upload example for each language and the MCP server package are linked from the API reference. The MCP server exposes the same operations as the tools replaceFileInDistribution, addFileToDistribution and getJobStatus, and ships a skill, migrate-from-taskrunner, that walks an AI assistant through the procedure on this page.
Migration checklist¶
- Replace the EntryStore cookie login with
POST $API/auth/loginand sendX-Auth-Tokenon every request. - Change the base URL from
https://<installation>/taskrunner/v1to$API. - Keep
replaceFilecalls as they are, apart from the URL and header. - Keep
addFilecalls as they are too, and take the new file's URI fromresultUrlon the finished job instead ofprototypeURIon the response. - Expect
202instead of200on upload, and storejobIdas a 64-bit integer or string. - Send the token when polling
GET /job/{jobId}, and compare against the upper-case status values. - Handle
413(file too large) and400(invalid filename) as new client-side failures. - Expect
422when the wrong kind of URI is passed, which Taskrunner only reported as a failed job.