Skip to content

Annotate one field

PATCH
/orgs/{org}/config/fields/{module}/{apiName}
curl --request PATCH \
--url 'https://api.sloose.com/orgs/org_9f3c/config/fields/accounts/Account_Name?connector=con_8f2a' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'If-Match: "7"' \
--data '{ "description": "example", "format": "example", "examples": [ "example" ], "aliases": [ "example" ], "excludeFromAi": true, "derived": true, "defaultMapping": { "mode": "column", "source": "example", "staticValue": "example", "staticPickedIn": { "connection": "example", "module": "example", "id": "example", "name": "example" }, "transform": "example", "skip": true, "searchField": "example", "searchMethod": "example", "searchExpression": "example", "patch": { "when": [ "pending" ], "overwrite": "always" }, "files": { "sheet": "example", "holds": "name", "separator": "example" }, "key": true, "keyMethod": "example", "keyExpression": "example", "onNone": "empty", "onSeveral": "ask" }, "excluded": true, "requiredForImports": "waivable", "writtenAs": "upper", "mustBe": { "rule": "example", "says": "example" }, "everyModule": true }'

Changes a single field’s annotation without sending the module’s whole set. A field is a connection’s: ?connector= names which, as the wizard does for the import it is working on. It is required: nothing picks one for a request that does not say (design §14.8).

The body is the field’s whole annotation. A property it leaves out is cleared, so { "aliases": [...] } alone also takes away the description, the default mapping and excludeFromAi. Send the annotation as you read it — from the module’s field list or the resolved configuration — with your change made, and If-Match the version you read it at: a write made against a version the organisation has since moved on from is refused with 409 instead of putting back what somebody else changed. The version is checked as part of the write itself, so of two writes sent under one version only the first lands.

The answer carries registryVersion only when you sent If-Match: one past the version you sent. Without it — no header, or * — the write lands on whatever version the organisation is at, and nothing here knows which version your copy of the field was read at. 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 field again, or send If-Match.

To add or take back ONE alias, POST or DELETE …/{apiName}/aliases changes that and nothing else, with no If-Match to send.

A field the CRM no longer returns can be annotated here. The module page keeps its row, because an older template may still name it, and offers its description, format, aliases and examples, which imports and the AI still read. A field the module has no row for is not found (404), and nothing of the request is written, everyModule included. It is 404 because the PATH names the field, the answer for a resource that is not there; the routes that name fields in their BODY (PATCH …/fields/{module}, PUT …/annotations, the bundle) answer 422 UNKNOWN_FIELDS for one instead.

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.

module
required

The module’s key or CRM API name — either is accepted.

string
Example
accounts

The module’s key or CRM API name — either is accepted.

apiName
required

The field’s CRM API name.

string
Example
Account_Name

The field’s CRM API name.

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
description
string
format
string
examples
Array<string>
aliases
Array<string>
excludeFromAi
boolean
derived
boolean
defaultMapping
object
mode
string
Allowed values: column static expression search skip
source
string | null
staticValue
string | null
staticPickedIn
object
connection
required
string
>= 1 characters <= 100 characters
module
required
string
>= 1 characters <= 200 characters
id
required
string
>= 1 characters <= 200 characters
name
required
string | null
<= 500 characters
transform
string | null
skip
boolean
searchField
string | null
searchMethod
string | null
searchExpression
string | null
patch
object
when
Array<string>
Allowed values: pending created updated exists skipped filtered guarded dryrun error blocked
overwrite
string
Allowed values: always if-absent
files
object
sheet
string | null
>= 1 characters
holds
required
string
Allowed values: name name-no-extension path path-end pattern row
separator
string | null
>= 1 characters <= 5 characters
key
boolean
keyMethod
string | null
keyExpression
string | null
onNone
string | null
Allowed values: empty skip ask
onSeveral
string | null
Allowed values: ask first skip empty
excluded
boolean
requiredForImports
Any of:
boolean
writtenAs
string
Allowed values: upper lower title
mustBe
object
rule
required
string
>= 1 characters <= 500 characters
says
required
string
>= 1 characters <= 200 characters
everyModule

Also set excluded on the field of this API name in every other module of this connection — the flag alone, since each module’s other annotations are its own. The body has to carry excluded. Commits with this field’s own annotation, under one version.

boolean

The field as it now stands.

Media typeapplication/json
object
field
required

A destination field definition, plus present, removedAt and the organisation’s annotation. destinationKeeps: true marks a field the destination keeps for itself and no import can write (a tag list written through an API of its own, a record’s status, a stamp): the same list that keeps it off an import’s mapping. It says nothing of curation (annotation.excluded), and a field without it carries no such key.

object
key
additional properties
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
alsoOn

With everyModule: the other modules whose field of this name had its flag changed.

Array<string>
Examplegenerated
{
"field": {
"additionalProperty": "example"
},
"registryVersion": 1,
"alsoOn": [
"example"
]
}

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

No such module, field or connection, or it is not visible to this session.

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 field is given a case its kind does not take (code: WRITTEN_AS_NOT_FOR_KIND, each named in fields with its kind and the cases it takes: a website takes none, an email lower case only), or a Must be rule that reads anything but the value, your helpers and plain built-ins (code: INVALID_RULE, each named in fields with the rule and why). Nothing was written.

Media typeapplication/json
object
error
required

Human-readable explanation.

string
code

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

string
fields

WRITTEN_AS_NOT_FOR_KIND: each field given a case its kind does not take. INVALID_RULE: each field given a Must be rule that reaches past the value, and why.

Array
Any of:
object
module
required
string
apiName
required
string
kind
required

The field’s kind, as discovery last read it.

string
writtenAs
required
string
Allowed values: upper lower title
takes
required

The cases this kind takes: none for a website, lower for an email.

Array<string>
Allowed values: upper lower title
key
additional properties
Example
{
"fields": [
{
"writtenAs": "upper",
"takes": [
"upper"
]
}
]
}

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