Skip to content

Apply a registry document

PUT
/orgs/{org}/config/registry
curl --request PUT \
--url 'https://api.sloose.com/orgs/org_9f3c/config/registry?connector=con_8f2a' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'If-Match: "7"' \
--data '{ "version": 1, "modules": [ { "seedMappings": "example", "key": "example", "apiName": "example", "label": "example", "singular": "example", "singularLabel": "example", "color": "example", "defaultEnabled": true, "uniqueFields": [ "example" ], "defaultDuplicateCheck": { "searchField": "example", "searchMethod": "example", "expression": "example" }, "excludedFields": [ "example" ], "child": { "of": "example", "via": "example", "parentNeedsRows": true, "pointer": "example", "maxRows": "off", "layouts": { "additionalProperty": { "name": "example", "maxRows": "off", "required": [ "example" ] } }, "defaultLayout": "example" }, "stockEffect": { "field": "example", "label": "example", "direction": "up" } } ], "expressionContext": "example", "apiDelayMs": 1, "systemExcludedFields": [ "example" ], "dateFormat": "DMY", "timezone": "example" }'

Replaces the organisation’s curation with the document, in one step. Every module it names must exist in the latest discovery. A module the CRM offers that the document leaves out is disabled; one gone from the CRM keeps whether it was chosen, and comes back with it if the CRM offers it again — unless the document names no module, which chooses nothing at all. Bumps registryVersion, which is how a client knows a template was saved against an older shape.

org
required

The organisation id the session was issued for. A token for one organisation can never read another.

string
Example
org_9f3c

The organisation id the session was issued for. A token for one organisation can never read another.

connector

The connection this is about, by id: one of the organisation’s, or your own. REQUIRED: absent or empty is 400 CONNECTION_REQUIRED, listing the connections this bearer may name, because nothing picks one for a request that does not say (design §14.8). Any other — another organisation’s, or another person’s — is 404 CONNECTION_NOT_FOUND.

string
Example
con_8f2a

The connection this is about, by id: one of the organisation’s, or your own. REQUIRED: absent or empty is 400 CONNECTION_REQUIRED, listing the connections this bearer may name, because nothing picks one for a request that does not say (design §14.8). Any other — another organisation’s, or another person’s — is 404 CONNECTION_NOT_FOUND.

If-Match

The registryVersion this change was made against, as "7" or 7 — a weak tag (W/"7") is refused, since If-Match uses strong comparison. Sent, the write is refused with 409 (code: REGISTRY_CONFLICT, the current version in the body) when the organisation has moved since, and otherwise answers the version it made: one past the version sent for a write made in one transaction, or the version sent itself for a request that asks for no change (an empty PATCH /config/writing), since it makes none. A bundle (POST /config/bundle) is several transactions and only its first waits on this version: it answers the version its own bumps took the organisation to — each part bumps only when it writes something, so a push of what is already there answers the version sent — and none — nor an etag — when another write landed between them; one landing after them, while its templates are saved, withholds the etag alone. Omitted, there is no condition, and * is no condition either — and a write with no condition answers no registryVersion (nor, from a bundle, an etag), since nothing says which version it was made from. A value that is neither is 400 (code: BAD_IF_MATCH) rather than ignored — a precondition silently dropped looks like conflict detection and is not.

string
Example
"7"

The registryVersion this change was made against, as "7" or 7 — a weak tag (W/"7") is refused, since If-Match uses strong comparison. Sent, the write is refused with 409 (code: REGISTRY_CONFLICT, the current version in the body) when the organisation has moved since, and otherwise answers the version it made: one past the version sent for a write made in one transaction, or the version sent itself for a request that asks for no change (an empty PATCH /config/writing), since it makes none. A bundle (POST /config/bundle) is several transactions and only its first waits on this version: it answers the version its own bumps took the organisation to — each part bumps only when it writes something, so a push of what is already there answers the version sent — and none — nor an etag — when another write landed between them; one landing after them, while its templates are saved, withholds the etag alone. Omitted, there is no condition, and * is no condition either — and a write with no condition answers no registryVersion (nor, from a bundle, an etag), since nothing says which version it was made from. A value that is neither is 400 (code: BAD_IF_MATCH) rather than ignored — a precondition silently dropped looks like conflict detection and is not.

Media typeapplication/json
object
version
integer
modules
required
Array<object>
object
seedMappings

seedMappings is no longer a module setting: a mapping a new import starts from belongs to the field it is about. Set defaultMapping on the field annotation — PATCH /orgs/{org}/config/fields/{module}/{apiName}, or fields/<module>.json in a configuration repository. Values already stored were moved by migration 0035.

key
required
string
/^[a-z][a-z0-9_]*$/
apiName
required
string
>= 1 characters
label
required
string
>= 1 characters
singular
required
string
/^[A-Za-z_$][\w$]*$/
singularLabel

One record as the CRM names it in words (“Sales Order”), which sentences say; singular is the identifier expressions use (“SalesOrder”). Read-only: discovery takes it from the CRM, so a pushed value is ignored. Absent until a discovery has read it, when a reader says singular.

string
color
string
defaultEnabled
boolean
uniqueFields
Array<string>
defaultDuplicateCheck
object
searchField
string
searchMethod
string
expression
string
excludedFields
Array<string>
child
object
of
required
string
/^[a-z][a-z0-9_]*$/
via
required
string
>= 1 characters
parentNeedsRows
boolean
pointer
string
>= 1 characters
maxRows
Any of:
integer
> 0
layouts
object
key
additional properties
object
name
required
string
maxRows
Any of:
integer
> 0
required
required
Array<string>
defaultLayout
string
>= 1 characters
stockEffect
object
field
required
string
>= 1 characters
label
required
string
>= 1 characters
direction
required
string
Allowed values: up down
expressionContext
string
/^[A-Za-z_$][\w$]*$/
apiDelayMs
integer
<= 60000
systemExcludedFields
Array<string>
dateFormat
string
Allowed values: DMY MDY YMD
timezone

The organisation’s IANA timezone, which helpers.today() answers in. Read-only: it is taken from the CRM at sign-in, so a pushed value is ignored.

string
<= 64 characters

Applied.

Media typeapplication/json
object
ok
required
boolean
registryVersion

The version the organisation is at after this write, to send as the next write’s If-Match: one past the version you sent in If-Match for a write made in one transaction (a bundle, several, answers the version its own bumps took the organisation to, or none when another write landed between them), or that version itself for a request that asks for no change (an empty PATCH /config/writing, which writes nothing and makes no version; sending the value the organisation already has still writes, and moves it). Only a write sent with a version in If-Match answers one. Without (no header, or *), the write lands on whatever version the organisation is at, and nothing on the server knows which version your picture of the configuration was built from: another administrator’s change may be inside the number, and sent back as If-Match it would let your next write overwrite that change unseen. So it is left out. To write again, read the configuration first (its GET answers the version), or send If-Match.

number
modules
required
Array<string>
Example
{
"ok": true
}

The request — its body or its query — did not match the schema (issues carries the Zod issue list), or: The request named no connection (code: CONNECTION_REQUIRED, with connections: the ones this bearer may name). Nothing picks one for a request that does not say (design §14.8).

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"
}

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 bearer’s role is too low (code: ROLE_REQUIRED), or it was issued for a different organisation; the organisation has been closed (code: ORG_CLOSED, either kind of bearer); the person is banned (code: BANNED, a session); or it is a session that is signed in but in no organisation (code: NO_ORG): one that never joined one, or whose person was taken out of the one it was in, or left it. Signing in again changes nothing for NO_ORG; choosing or making an organisation does.

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"
}

?connector= names a connection this person may not use: another organisation’s, or another person’s (code: CONNECTION_NOT_FOUND).

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 organisation’s configuration has changed since the version in If-Match; the current one is in the body.

Media typeapplication/json
object
error
required
string
code
required
string
Allowed values: REGISTRY_CONFLICT
registryVersion
required
number
key
additional properties
Example
{
"code": "REGISTRY_CONFLICT"
}

The document does not read (INVALID_REGISTRY), names a module the latest discovery does not hold (UNKNOWN_MODULES), gives a key another module holds (KEY_CLASH), gives a default match rule a field the destination cannot match by (UNMATCHABLE_FIELD, each rule named in rules), or enables a subform (MODULE_IS_SUBFORM, each named in subforms).

Media typeapplication/json
object
error
required
string
code
required
string
missing

UNKNOWN_MODULES only: the modules the latest discovery does not hold.

Array<string>
subforms

MODULE_IS_SUBFORM only: each subform named, which is reached from its parent and is never one an import writes to.

Array<string>
rules

UNMATCHABLE_FIELD only: each default match rule or template key that looks in a field the destination does not take with the method it asks, and why.

Array<object>
object
module
required
string
field
required
string
words
required

In words: the field cannot be matched with this method, and why.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example",
"missing": [
"example"
],
"subforms": [
"example"
],
"rules": [
{
"module": "example",
"field": "example",
"words": "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