Save, update, detach, take the latest, choose another, or drop the template
const url = 'https://api.sloose.com/orgs/org_9f3c/imports/imp_4d1a/template';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"action":"new","templateId":"example","version":1,"name":"example","visibility":"private","registryVersion":1}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.sloose.com/orgs/org_9f3c/imports/imp_4d1a/template \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "action": "new", "templateId": "example", "version": 1, "name": "example", "visibility": "private", "registryVersion": 1 }'The six commands between an import and its template (design §2.2; choose and drop are §6 of the draft-and-refine design). Each is one write under version: the import and whatever it writes to the template land together or not at all, and are refused while a run holds the import.
new— any role, on an import they may change: a template from the import’s recipe, its first version, and the import pointed at it. Each flow’s source is described by what it is now — its reader and its place among the import’s sources — because a template is run again on next month’s file.update— the builder role or above, and for a private template its creator or an administrator: the recipe becomes the template’s next version, only while the template is still at the version this import copied (409 TEMPLATE_MOVEDotherwise, naming the version it is at, who made it and when), and never for a template a configuration repo manages (409 TEMPLATE_MANAGED). The import moves to the version it made. An unchanged recipe writes nothing: a version that moved for nothing would tell every other import from the template that it had moved on.detach— the pointer is cleared; the recipe stays, as the import’s own. Detaching an import that has no template changes nothing and moves no version.take-latest— the template’s current recipe replaces the import’s, and each of the template’s flows is paired with a source the import holds: the source already feeding a flow of that id, then a worksheet of the same name, then — only when exactly one of each is left — the one left. A source paired with nothing keeps a flow of its own: the one it fed, with this import’s recipe for it. A flow of the template paired with nothing stays in the recipe, for a file still to come.choose— for a file that does not fit the template the import was started from (design §6, Choose another template): the chosen template’s current recipe replaces the import’s and the import points at it, at that version. Each file the import holds takes one of its recipes as a file arriving does — the recipe made for a worksheet of its name, where one alone was, else the first still waiting, in the template’s order, the files taken in the order the import holds them — and a file left with none starts a recipe of its own, empty. Nothing of the recipe it replaces is kept: it was the other template’s. A template the caller cannot see is not found.drop— Start without a template (design §6): the pointer and the recipe both go, with the modules it chose and the draft’s account of it, and each file keeps its rows and its cleaning under a recipe of its own, empty, as an import started without a template would hold them. An import with no template changes nothing and moves no version.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The org id the session was issued for. A token for one org can never read another.
Example
org_9f3cThe org id the session was issued for. A token for one org can never read another.
The import id.
Example
imp_4d1aThe import id.
Request Bodyrequired
Section titled “Request Bodyrequired”object
new: save this import’s recipe as a new template and point the import at it. update: write it as the next version of the template the import came from. detach: forget the template; the recipe is the import’s own. take-latest: replace the recipe with the template’s current version. choose: take another template (templateId) — its current version replaces the recipe, and the import points at it. drop: start without a template — the template and its recipe are both forgotten; the files and their cleaning stay.
choose only, and required there: the template to take, one the caller can see — shared with the org, or their own.
The import’s version this was decided against — from the last read or write.
new only: what the template is called. The import’s name when absent.
new only: private (the default) is yours alone; org shares it with everyone here, which needs the builder role and a plan with shared templates.
The registryVersion the recipe was built against: the configuration’s registry.version as you loaded it (GET …/config/resolved). Read only when this request writes a recipe to the template — a create; an update carrying config; an import’s new, and its update when the recipe changed — and then stored as the template’s registryVersion, so that a change to the configuration made since can be told. Omitted or null there, the template is stamped with none (null): nothing on the server knows which version your recipe saw, and the version current when the save arrives would claim it had seen changes it had not. A version the org has not reached is refused there (400, code: BAD_REGISTRY_VERSION, with the current registryVersion). A request that writes no recipe to a template — a rename, detach, take-latest, choose, drop, an update of an unchanged recipe — ignores it and keeps the stamp the template has.
Responses
Section titled “Responses”update, detach, take-latest, choose and drop: the import as it now stands, and — after update, take-latest and choose — the template it now has. template is absent after detach and drop, which leave the import without one.
object
object
The connection Target names; null until one is chosen.
The template this import was started from or saved as.
The template version it copied: “the template has moved on” compares this.
Who started it — the person, or the person a token acts as. Null only for an import a schedule started, which is nobody’s own.
The token held, when one was.
Where it stands. An import being deleted is not returned at all: it reads as gone the moment its delete is accepted.
Whichever step the wizard of the day left it on, as that wizard names it.
The write precondition: every change names the version it was made against, and a stale one is refused 409 IMPORT_CHANGED.
The run that holds the import; every other write is refused while one does.
The import’s own flows, value maps and run policy, migrated to the current schema version on read. Null until the wizard writes one, or when it could not be migrated.
Migration steps applied to the recipe on read.
object
Where the rows came from: file, paste, generated, connection.
Which reader read the bytes: delimited or xlsx.
The SHA-256 of the file stored for the source, hex: the identity of its bytes, which changes with every new file and never with a new reading of the same one. With how they are read (reader, options, sheetName), what says an AI answer that proposed a change to the file (a reshape, a sample, a re-read) was not taken: the same bytes, read the same way, are still the file it was proposed for. Null for a file stored before it was kept; the sheets of one workbook share their workbook’s.
Which kept answer made this file — { turnId, index }, the turn and the reshape, sample or re-read in its targets — or null: what says such an answer was used, on the server and in the app alike, where the file’s shape cannot. Written with every file stored for the source and every new reading of it, from the upload’s madeByAnswer, and null for any other.
object
How this file was reshaped from the file as read at its header row (#1363): the steps in order, each counted on the grid the ones before it left, every row a step named by its place marked so another file’s can be found by it. Written with every file stored for the source and every new reading of it, from the upload’s reshape, and null for any other.
object
object
object
One letter a cell: b blank, n a number, t other text.
Its text cells, digits taken out, case and spaces folded, joined by |.
What the reader needs to read the file again: delimiter, sheet, header row — in the shape this build reads, whatever shape they were stored in. They are stored with the version of that shape and walked forward when read; that version is not shown.
The worksheet’s name, for a source read from one; null for text. The reader finds the sheet by its place (options.sheet); a template names it by this, because a name survives next month’s workbook having its tabs reordered.
The size of the current cleaning revision; null when the source has none.
The size of the current revision of its work — the guesses waiting on it, the ones turned down, how each used one was found; null when the source has none.
The recipe flow this source feeds, paired by id and never by label or position.
The draft’s account of itself — which parts it drafted, which it could not and why — as the wizard wrote it, with its schemaVersion; null when no draft has been made.
The versions this import keeps instead of the current ones (#559): namespace → { version, library }. Empty when it keeps none. A pin whose library is no longer the one current under its name keeps nothing — the library was removed since — and the page says so.
object
object
The template the action wrote or read: the new one, the updated one, the one whose latest was taken, the one chosen. Absent after detach and drop.
object
The connection it was built for, when it names one: a template saved from an import records that import’s, and an import started from it pre-selects that one. Null on a template that names none — pushed from a configuration repository, or written by an agent without one — which is picked for on Target, among the connections of its kind.
The configuration version the recipe was built against, as its save REPORTED it (#616): an agent’s save over MCP stamps the version it checked the recipe against, and a repository’s push the version it wrote (none when another write landed while it wrote the configuration, which it checks before its templates; one landing while the templates are saved is outside that check, and the stamp stays, #650); any other save, the registryVersion it sent — a label the server stores for any version the org has reached, not one it checked. null when the save said none.
bundle:<file> when pushed from a config repo; null when built by a person.
The kind of connection this template imports into — zoho_crm. Null on a template saved before kinds were recorded, which is read as Zoho CRM, the only kind there was.
Which version of the template this is. “Update the template” writes the next one; an import that copied an earlier one is told the template has moved on.
sdk when a config repo owns the template: changes arrive by the next push, and updates from an import are refused. Null when people own it.
When a run last started from it — a run authorised for an import made from it, or naming it with no import, a dry run included. Null for one no run has started from. Runs are purged, so this is kept, not worked out; it moves no version.
Migrated to the current schema version on read. Null when it could not be migrated.
Migration steps applied on read. Non-empty means the stored row is from an older build.
Example
{ "import": { "status": "open", "sources": [ { "reshape": { "steps": [ { "marks": [ { "from": "start" } ] } ] } } ] }, "template": { "visibility": "private", "managedBy": "sdk" }}new: the import pointed at its new template, and the template.
object
object
The connection Target names; null until one is chosen.
The template this import was started from or saved as.
The template version it copied: “the template has moved on” compares this.
Who started it — the person, or the person a token acts as. Null only for an import a schedule started, which is nobody’s own.
The token held, when one was.
Where it stands. An import being deleted is not returned at all: it reads as gone the moment its delete is accepted.
Whichever step the wizard of the day left it on, as that wizard names it.
The write precondition: every change names the version it was made against, and a stale one is refused 409 IMPORT_CHANGED.
The run that holds the import; every other write is refused while one does.
The import’s own flows, value maps and run policy, migrated to the current schema version on read. Null until the wizard writes one, or when it could not be migrated.
Migration steps applied to the recipe on read.
object
Where the rows came from: file, paste, generated, connection.
Which reader read the bytes: delimited or xlsx.
The SHA-256 of the file stored for the source, hex: the identity of its bytes, which changes with every new file and never with a new reading of the same one. With how they are read (reader, options, sheetName), what says an AI answer that proposed a change to the file (a reshape, a sample, a re-read) was not taken: the same bytes, read the same way, are still the file it was proposed for. Null for a file stored before it was kept; the sheets of one workbook share their workbook’s.
Which kept answer made this file — { turnId, index }, the turn and the reshape, sample or re-read in its targets — or null: what says such an answer was used, on the server and in the app alike, where the file’s shape cannot. Written with every file stored for the source and every new reading of it, from the upload’s madeByAnswer, and null for any other.
object
How this file was reshaped from the file as read at its header row (#1363): the steps in order, each counted on the grid the ones before it left, every row a step named by its place marked so another file’s can be found by it. Written with every file stored for the source and every new reading of it, from the upload’s reshape, and null for any other.
object
object
object
One letter a cell: b blank, n a number, t other text.
Its text cells, digits taken out, case and spaces folded, joined by |.
What the reader needs to read the file again: delimiter, sheet, header row — in the shape this build reads, whatever shape they were stored in. They are stored with the version of that shape and walked forward when read; that version is not shown.
The worksheet’s name, for a source read from one; null for text. The reader finds the sheet by its place (options.sheet); a template names it by this, because a name survives next month’s workbook having its tabs reordered.
The size of the current cleaning revision; null when the source has none.
The size of the current revision of its work — the guesses waiting on it, the ones turned down, how each used one was found; null when the source has none.
The recipe flow this source feeds, paired by id and never by label or position.
The draft’s account of itself — which parts it drafted, which it could not and why — as the wizard wrote it, with its schemaVersion; null when no draft has been made.
The versions this import keeps instead of the current ones (#559): namespace → { version, library }. Empty when it keeps none. A pin whose library is no longer the one current under its name keeps nothing — the library was removed since — and the page says so.
object
object
The template the action wrote or read: the new one, the updated one, the one whose latest was taken, the one chosen. Absent after detach and drop.
object
The connection it was built for, when it names one: a template saved from an import records that import’s, and an import started from it pre-selects that one. Null on a template that names none — pushed from a configuration repository, or written by an agent without one — which is picked for on Target, among the connections of its kind.
The configuration version the recipe was built against, as its save REPORTED it (#616): an agent’s save over MCP stamps the version it checked the recipe against, and a repository’s push the version it wrote (none when another write landed while it wrote the configuration, which it checks before its templates; one landing while the templates are saved is outside that check, and the stamp stays, #650); any other save, the registryVersion it sent — a label the server stores for any version the org has reached, not one it checked. null when the save said none.
bundle:<file> when pushed from a config repo; null when built by a person.
The kind of connection this template imports into — zoho_crm. Null on a template saved before kinds were recorded, which is read as Zoho CRM, the only kind there was.
Which version of the template this is. “Update the template” writes the next one; an import that copied an earlier one is told the template has moved on.
sdk when a config repo owns the template: changes arrive by the next push, and updates from an import are refused. Null when people own it.
When a run last started from it — a run authorised for an import made from it, or naming it with no import, a dry run included. Null for one no run has started from. Runs are purged, so this is kept, not worked out; it moves no version.
Migrated to the current schema version on read. Null when it could not be migrated.
Migration steps applied on read. Non-empty means the stored row is from an older build.
Example
{ "import": { "status": "open", "sources": [ { "reshape": { "steps": [ { "marks": [ { "from": "start" } ] } ] } } ] }, "template": { "visibility": "private", "managedBy": "sdk" }}The request did not match the schema (issues carries the Zod issue list); choose named no templateId (code: INVALID_BODY); or new or update sent a registryVersion this org’s configuration has not reached (code: BAD_REGISTRY_VERSION, with the current registryVersion).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}No bearer, or one that is expired, revoked or no longer resolves to a member.
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}An operator acting on somebody else’s import (code: NOT_YOURS); an operator updating or sharing a template (code: ROLE_REQUIRED); updating somebody else’s private template without being an administrator (code: NOT_TEMPLATE_OWNER); or a plan that cannot share templates (code: FEATURE_SHARED_TEMPLATES).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}No such import, template — for choose, one the caller cannot see is not found — or the connection the import names, or it is not visible to this session.
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}Somebody changed the import since this version (code: IMPORT_CHANGED, with its version and updatedBy); a run holds it (code: IMPORT_RUNNING); the template has moved on since the import copied it (code: TEMPLATE_MOVED, with its version, updatedBy and updatedAt); a configuration repo manages the template (code: TEMPLATE_MANAGED, with its sourceRef); the import has no template to update or take from (code: NO_TEMPLATE), or no recipe to save (code: NO_RECIPE); or a stored recipe, or a source’s reader options, came from a newer build (code: FROM_FUTURE, which is refused before anything is written).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}The import’s stored recipe (code: INVALID_RECIPE) or the template’s (code: INVALID_TEMPLATE) is not usable under the current schema, with its issues; or it could not be read at all (code: UNREADABLE).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}