Skip to content

Close an authorised run, and record how it went

POST
/entitlements/runs/{runId}/progress
curl --request POST \
--url https://api.sloose.com/entitlements/runs/run_7c2e/progress \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "rowsWritten": 1, "rowsCreated": 1, "rowsUpdated": 1, "rowsFailed": 1, "done": true, "outcome": "complete", "modules": [ "example" ], "inOrder": true, "finished": true, "totals": { "created": "example", "updated": "example", "failed": "example" }, "error": "example" }'

Call this once with done: true when the import finishes (or in batches before that, for the history’s created/updated/failed counts). Rows are metered on the write path, not here: every record goes through /orgs/{org}/connectors/{id}/records, which admits the row with the ledger before writing, so this report’s rowsWritten is accepted for older clients and ignored by the meter. The D1 run row is the history; the answer carries the meter’s own total and, when the run has been stopped for reaching the rows one import may write, stopped saying so.

The threshold is the LOWER of the run’s own declaredRows and the plan’s current rows_per_run, and a write that would cross it is refused before it reaches the CRM.

A run ends once, and how it ends is the meter’s (runStatus in the answer): a close that arrives after something else ended the run — the server’s abandoned, when nobody renewed its lease; a stop’s over_limit — is recorded as that ended it, whatever the close says, and a close whose history write was lost is put right by any later report. The history’s rows, and its created, updated and failed counts over every report the meter took, are set from the meter’s snapshot (totals), not added up — and so are they when the server ends the run, which records every row the meter admitted, not only those a report carried. A run of an import reports only while it holds its import: after its lease has run out, anything but a close is refused 409 LEASE_LOST.

runId
required

The run id from POST /entitlements/runs/authorise.

string
Example
run_7c2e

The run id from POST /entitlements/runs/authorise.

Media typeapplication/json
object
rowsWritten

Rows written since the last report. Non-negative.

number | null
rowsCreated

Records created since the last report — signed: a negative number takes back one counted before, as a record first counted as created and then found to be an update.

number | null
rowsUpdated

Records updated since the last report — signed, as rowsCreated is.

number | null
rowsFailed

Rows that failed since the last report — signed: a negative number takes back a failure counted before, as a failed row that succeeds on a later attempt.

number | null
done

True on the final report. Closes the run and settles the meter.

boolean | null
outcome

How the run ended. Only meaningful with done: true.

string | null
Allowed values: complete cancelled error
modules

Modules the run touched. At most 50 are kept.

Array<string> | null
inOrder

The engine says the run ended in order (it finished every call of every row it began and stopped at the top of a window, or reached the end of the file). Only on the close (done: true), and kept only where the ledger ended the run as that close said, or had stopped it at its row limit before the close arrived, and where the server saw nothing stop it (a spent allowance) and holds no unanswered attempt of it; a late close after the server abandoned the run keeps nothing, and the page leaves the word out when an outcome report of the run was given up on or refused. Never worked out from outcome.

boolean | null
finished

The engine says it FINISHED (#2237): its last window completed — every row walked, none left part-written, no spent allowance — sent before any close, so that a page that goes before its close leaves a run the server can end complete rather than abandoned. Not a close (done absent): it is a report of the run, answered only to the credential that holds its lease, kept only while the run is open, and taken back by an unanswered record stored for the run.

boolean | null
totals
Any of:
object
created
updated
failed
error

Failure message, truncated to 2,000 characters.

string | null
key
additional properties

The period usage after this report — and, when the run has been stopped for going past the rows one run may write, stopped saying so.

Media typeapplication/json
object
periodStart
required
string
periodEnd
required
string
rowsWritten
required
number
rowsOverage
required
number
creditsUsed
required
number
runs
required

Runs counted this period, through any of the organisation’s connections: each once, at the first row it sent to be written, whether or not the CRM took that row.

number
byServer

With a run that has ended: the server itself ended it complete on the engine’s finishing word, before this report (#2279). What the run’s history records as who ended it.

boolean
closedInOrder

With a run that has ended: its close was in order, as the meter remembers it (#2279, #2281). The history keeps it only where it holds no unanswered record of the run.

boolean
credited
required

How many of this report’s rows were counted. Zero for a report against a run that has already finished or been stopped.

number
stopped

Present when the server has STOPPED this run, and on every report after it, so a caller that missed the first answer is told the same thing. Whether THIS batch was counted is credited: the batch that crossed the ceiling was counted in full, and every one after it counts nothing. Stop the import and tell the person why.

string
Allowed values: LIMIT_ROWS_PER_RUN
rowsPerRun

With stopped: the number of rows this run was held to.

number
accepted
required

Was this report taken — which is not the same as how many rows it metered. A batch of only failed rows meters nothing and is still a report about a running import. False for a report against a run that has finished, been cancelled, or been stopped.

boolean
rowsWrittenTotal
required

Every row this run has been metered for, not just this report’s. The run history is set from it rather than accumulated, so a write that was lost is put right by the next report.

number
runStatus

How the run stands after this report, as the meter holds it: authorised while it runs, otherwise how it ended — whatever this report says about itself. A close that arrives after the server ended the run (abandoned: nobody renewed its lease, or nothing was written under a run with no import for a day; over_limit: stopped at its ceiling) is recorded as the server ended it. Absent for a dry run, which the meter never holds.

string
Allowed values: authorised complete cancelled error over_limit abandoned
endedAt

With an ended runStatus: when it ended, in ISO — the same on every later report. Null for a run that ended before the meter kept the moment.

string | null
totals

The run as the meter holds it, in one snapshot: the rows it is held to (written, which is rowsWrittenTotal), the created, updated and failed rows over every report it took, not just this one’s, and their revision. Any of them can fall: a report’s counts are signed, so a correction takes one back, and a write the CRM refused is released from the rows. So the revision moves with every report taken and every row admitted or released, and the run history is set from the newest snapshot. A report whose write was lost is put right by the next, and a slow older one cannot undo it. Absent for a dry run.

object
written
required
number
created
required
number
updated
required
number
failed
required
number
rev
required
number
rowsAllowed
required

How many rows this run may write in total. While the run is authorised: the lower of what it declared and what the plan allows in one import, as the plan is now — so it FALLS if the plan is downgraded while the run is going, and a caller that honours it stops on the limit instead of being stopped past it. Once the run has been stopped it is the ceiling it was stopped for and does not move again, whatever the plan does next.

number
stoppedBy

With stopped: which ceiling bound. plan is the plan’s rows per run, which a higher plan raises; declaration is the number this run itself declared, which upgrading cannot change.

string
Allowed values: plan declaration
stoppedNow

With stopped: whether THIS report is the one that ended the run. False on every report after it.

boolean
stoppedWhen

With stopped: when the run was stopped, in ISO. The same value on every later report, so a caller recording it can retry.

string
Example
{
"stopped": "LIMIT_ROWS_PER_RUN",
"runStatus": "authorised",
"stoppedBy": "plan"
}

rowsWritten is negative or not a number.

Media typeapplication/json
object
error
required
string
key
additional properties
Examplegenerated
{
"error": "example"
}

No bearer, or one that no longer resolves: a session that is unknown or expired (code: AUTH_REQUIRED), or an API token that was revoked or expired (TOKEN_REVOKED, TOKEN_EXPIRED), whose organisation is gone (ORG_NOT_FOUND) or whose member or user row is (MEMBERSHIP_GONE).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

The run is an import’s and this is not the session or token that authorised it (code: NOT_YOUR_RUN) — a run is closed by the credential that started it; the bearer’s role is too low; or its organisation has been closed (code: ORG_CLOSED). Like every route behind a session: a session signed in but in no organisation is refused code: NO_ORG, a banned person code: BANNED, and a closed organisation code: ORG_CLOSED.

Media typeapplication/json
object
error
required
string
code
string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

No such run, or it has already been settled.

Media typeapplication/json
object
error
required
string
key
additional properties
Examplegenerated
{
"error": "example"
}

The run is an import’s, this report is not a close, and the run no longer holds its import (code: LEASE_LOST): only a close may come after the lease.

Media typeapplication/json
object
error
required
string
code
string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

The restore switch is on (code: MAINTENANCE): every route but /health and /robots.txt is refused before anything is read, except the operator’s own POST /staff/people/{id}/delete with the ADMIN_TOKEN. Sloose is down for maintenance. Please try again in a few minutes.

Media typeapplication/json
object
error
required
string
code
required
string
Allowed value: MAINTENANCE
Example
{
"code": "MAINTENANCE"
}
Retry-After
integer

Seconds until asking again is worth it (300 while the switch is on).

Report a problem with this page

sloose.com