raw_email to sha256_hashed_email might map the target’s value property to SHA2(NORMALIZE_EMAIL($source.value), 256). Once a rule exists, queries can resolve the target attribute from the source without a stored mapping.
The /derivations endpoints let you list, fetch, create, update, and delete rules. Read access follows collaborator sharing; create, update, and delete are restricted to admins on the company that owns the rule.
Concepts
Source, target, and transformation
Every rule has one source attribute (read through$source inside the transformation) and one target attribute (the value the rule produces). The mapping field on the request holds the transformation and mirrors mapping types with two differences:
- Only
value_mappingandobject_mapping(asRawValueMappingandRawObjectMapping) are accepted.cached_mappingis rejected because there is no source dataset to look values up from. - Expressions reference the source attribute’s shape through
$sourceinstead of source-column names. For anobjectsource,$source.<property>reads a property; for a primitive source,$sourceis the value.
Validation
Every transformation is validated before the rule is written. The API parses each expression, compiles it against a synthetic single-column table built from the source attribute, and type-checks the result against the target attribute using the same rules as a dataset mapping. Every required target property must be covered; unknown properties are rejected. If several problems are present in one mapping, they come back together as a single400.
Non-deterministic and dynamic functions like CURRENT_DATE, CURRENT_TIMESTAMP, and RAND are permitted. A derivation expression runs when a query resolves the rule, so a rule from birthdate to age in years is correct as of each query that uses it.
Cycle warnings
A rule fromnormalized_email to raw_email alongside one going the other way is a pair of correct rules, so a create or update that closes a cycle in the derivation graph is written anyway. The response returns a cyclic_derivation warning listing the attribute ids in the cycle. Cycle detection is bounded: only cycles of up to six attributes are reported, and at most ten come back per response. List and get responses do not compute warnings.
Permissions
A rule your company cannot see returns
404, not 403. Only Narrative can share a rule broadly, with all or with an exclusion set on collaborators.use.
Endpoints
GET /derivations
List the derivation rules your company can use. Filter with repeated source_attribute_id and target_attribute_id query parameters; both accept multiple ids and combine as AND.
{ "records": [ ... ] }. Warnings are empty on reads.
GET /derivations/{derivation_id}
Fetch a single rule by id. Returns 404 if the rule is not usable by your company.
POST /derivations
Create a rule. Requires an admin grant on attribute_derivations. The transformation is validated before the rule is written.
201 with the created rule and any warnings.
Error responses:
PATCH /derivations/{derivation_id}
Update fields on an existing rule. Requires an admin grant, and only the owning company can update. Only fields present in the request change; a changed mapping runs the same validation as create.
source_attribute_idandtarget_attribute_idare immutable — there is no key for them, and one sent anyway is ignored. Create a new rule instead.- Setting
fidelity_notetonullclears the note. Leaving the key out keeps the current value. - Unknown keys are rejected.
200 with the updated rule and any warnings.
DELETE /derivations/{derivation_id}
Permanently remove a rule. Requires an admin grant, and only the owning company can delete. To take a rule out of use while keeping it, PATCH active to false instead.
Request and response fields
Rule fields
string
required
Name of the rule, unique within the owning company. Up to 256 characters.
string
required
What the rule does, for whoever is deciding whether to accept derived data. Up to 2048 characters.
integer
required
The attribute the rule reads from through
$source. Immutable after create.integer
required
The attribute whose value the rule produces. Must differ from
source_attribute_id. Immutable after create.integer
required
The company that owns the rule. Must equal the caller’s company on create.
object
required
The transformation. Same shape as
value_mapping or object_mapping in Mapping types, except expressions reference $source instead of source-column names. cached_mapping is not allowed.boolean
required
The transformation loses information — for example, hashing.
boolean
required
The transformation is approximate — for example, bucketing an age into a range.
object
Which other companies may have the rule applied to their data. A rule grants one thing, so there is a single
use dimension. all and exclusion are reserved for Narrative-owned rules.string | null
Explains the
lossy and imprecise flags to whoever is deciding whether to accept derived data. Up to 2048 characters. PATCH with null clears the note.integer
default:"1"
Breaks ties when more than one rule reaches the same target attribute — cheapest first. Multi-step resolution sums the cost of every rule on a path and prefers the cheapest total. Minimum
1.boolean
default:"true"
Inactive rules are never applied.
Response-only fields
integer
Unique identifier of the rule.
string
ISO 8601 timestamp of creation.
integer
Id of the user who created the rule.
string
ISO 8601 timestamp of the last update.
integer
Id of the user who last updated the rule.
array
Populated on create and update responses; empty on reads. Each warning is an object; today the only
type is cyclic_derivation, whose cycle field lists the attribute ids visited in order (the closing step back to the first id is implied).Related content
Mapping types
The mapping shapes derivation transformations reuse.
Transformation functions
Functions available inside derivation expressions.
Attribute types
The source and target shapes a rule connects.
How Rosetta Stone works
Background on attributes, mappings, and normalization.

