Expressions
A mapping expression computes one value. Corma uses expressions in two directions:
- Inbound — Corma reads a connector and writes the result to a Corma user field. Configure it with
PUT /user-fields/{id}/mapping. - Outbound — Corma reads the Corma user and writes the result to a field of the connector, when it creates an account. Configure it with
PUT /connectors/{id}/field-mappings/{targetFieldId}.
The language is the same in both directions. Only the variables differ, and the first segment of a path says which set you are in.
An expression crosses the wire as a string, exactly as it is written. Corma parses it, so the API never exposes a syntax tree. An expression can hold 4096 characters.
Corma checks an expression when you store it. A path that the direction does not offer is refused with the code invalid_expression, and no mapping is written.
Variables: reading from a connector
An inbound variable is a path, and its first segment is the connector it reads from:
google.primaryEmail
google.name.fullName
personio.attributes.department
The paths are not guessed: GET /connectors/{id}/fields lists every field a connector exposes, and the id of a field is the variable to write. A field whose origin is custom is one the workspace defined in the connector itself; it is listed once Corma has read the catalog of that connector.
A path may cross a list with [*], which yields every matching value:
google.emails[*].address
Variables: reading the Corma user
An outbound variable always starts with user:
user.email
user.jobTitle
user.managerEmail
user.customFields.matricule
The paths are not guessed here either: GET /user-fields lists every field a Corma user carries, and user. followed by the id of a field is the variable to write. A field whose origin is custom is one the workspace defined; its identifier already starts with custom., and it is read as user.customFields.<key>.
Two rules apply to this direction only:
- Write the
idof the field, not the label an interface shows:user.jobTitle, notuser.job title. Every Corma user field can be read outbound, including the ones no connector may write into, such as the professional email. - A path that names a person —
user.managerEmail, or a custom field whose type isuser— must produce an email address or the identifier of the account in the connector. An expression that produces a display name resolves to nobody, and Corma writes nothing.
Functions
A function call takes arguments that are themselves values, variables or calls:
coalesce(google.name.fullName, google.name.familyName, google.primaryEmail)
if(google.suspended, "suspended", "active")
upper(trim(personio.attributes.department))
GET /expression-functions lists every function, with its arguments and the type it returns. Read that list rather than hard-coding one: functions are added over time.
Three fields of a function deserve attention:
paramsis the ordered list of arguments. The number of arguments comes from this list.variadicon the last argument means it repeats.concatdeclares one argument and accepts any number of values.valueson an argument closes it over a fixed list.date_addaccepts only those units, and the expression is refused if you send another. Offer them as a choice rather than free text.returnTypeisinheritwhen the function gives back one of its arguments.coalescereturns whatever its arguments hold, so its result has their type.
Literals
| Kind | How to write it | Example |
|---|---|---|
| Text | Double quotes | "active" |
| Number | Digits | 42 |
| Boolean | true or false |
true |
| Nothing | null |
null |
What an empty result means
An expression that resolves to nothing yields null. A mapping decides what happens then: by default Corma leaves the current value alone, so a connector that stops sending a field does not erase what another source wrote.
Examples
Inbound
A workspace reads its users from Google, and wants the display name to fall back twice:
coalesce(google.name.fullName, google.name.familyName, google.primaryEmail)
- A user with a full name gets it.
- A user with only a family name gets that.
- A user with neither gets their email address, so the field is never empty.
Outbound
The same workspace creates Google accounts, and wants the job title to come from Corma, with the department as a fallback:
coalesce(user.jobTitle, user.teamName)
A field Corma must not write at all is not deleted — it is switched off, with {"mode": "skip"}. Deleting the mapping restores Corma's own default instead. A field the connector needs to create an account cannot be switched off, and the API refuses it with the code invalid_mapping.