
Record generation is the process that changes your fixed content templates into personalized, dynamic content. When you use the API or JinJava tags, it fills in all dynamic parts, gets data from other sources, and uses Synerise's objects to create content that fits the situation.

While generating, dynamic fields can [use other basic fields (like text, numbers, true/false, or choices) from the same record](/docs/assets/brickworks/brickworks-jinjava-inserts#retrieving-values-from-fields), plus extra information you give in the request. If the generation is for a certain user profile, Brickworks will automatically save this as an [action](#events-generated) done by that user.


<div class="admonition admonition-important"><div class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg></div><div class="admonition-body"><div class="admonition-content">

When an object is generated, profile data and external source responses are [cached](/docs/assets/brickworks/limits) and used in subsequent requests.

</div></div></div>


## Events generated

Brickworks automatically generate events whenever records are generated in the context of a customer profile. This creates a comprehensive audit trail and feeds valuable data back into the Synerise platform for analytics, personalization optimization, and customer journey tracking. The following events are generated:

- [brickworks.generated](/docs/assets/events/event-reference/brickworks#brickworksgenerated)
- [brickworks.generated.error](/docs/assets/events/event-reference/brickworks#brickworksgeneratederror)  
    The error event is also generated when the profile doesn't belong to the audience.

## Distribution channels

You can distribute objects with record results in the following channels:

- Website (inject content into website source, web push notifications)
- Mobile (SMS, push notifications, in-app messages, mobile applications)
- Display advertising (digital signage)
- Email marketing

## Context

When generating a record, you can pass additional data to influence what it renders. Two optional parameters are available for this — `context` and `fieldContext`:

- **`context`** — a global JSON object. Any [Jinjava field](/docs/assets/brickworks/schema-field-types#jinjava-code) in the record can read its values at generation time.
- **`fieldContext`** — a per-field JSON object. Each key is the **API name** of a schema field (the identifier assigned to the field when the schema was created), and the parameters nested under it are passed exclusively to that field.

  Both support nested objects and work identically in the API and in Jinjava tags:


  <div class="content-tabs" data-tab-group="tabgrp-1251">
  <div class="tab-buttons"><button class="tab-button" data-tab-id="tabgrp-1251-0" data-tab-group="tabgrp-1251" data-tab-active="true">API</button><button class="tab-button" data-tab-id="tabgrp-1251-1" data-tab-group="tabgrp-1251">Jinjava tags</button></div>

  <div class="tab-panel" data-tab-id="tabgrp-1251-0" data-tab-group="tabgrp-1251" data-tab-active="true">

  <pre><code class="language-json">{
  "context": {
    "catalog": {
      "itemId": "78363"
    },
    "itemId": "1"
  },
  "fieldContext": {
    "recoField": {
      "itemId": "e579487933852f3a83abd9e840175c"
    }
  }
  }</code></pre>

  </div>

  <div class="tab-panel" data-tab-id="tabgrp-1251-1" data-tab-group="tabgrp-1251">

  <pre><code class="language-jinja">{% set context = {"catalog": {"itemId": "78363"}, "itemId": "1"} %}
  {% set fieldContext = {"recoField": {"itemId": "e579487933852f3a83abd9e840175c"}} %}

  {% brickworksgeneratevar schemaId=SCHEMA_ID recordId=RECORD_SLUG context=context fieldContext=fieldContext %}
  {{ brickworks_result|tojson }}
  {% endbrickworksgeneratevar %}</code></pre>

  </div>
  </div>


  Brickworks uses them to:

- populate [dynamic fields](/docs/assets/brickworks/schema-field-types#dynamic-types) with relevant data
- customize [Synerise object](/docs/assets/brickworks/synerise-objects) behavior
- fetch [external data](/docs/assets/brickworks/schema-field-types#external-data) with context-specific parameters

This means the same record can render differently depending on the context you provide.

### `context`

`context` is a [global JSON object](/docs/assets/brickworks/brickworks-jinjava-inserts#retrieving-context) available to every [Jinjava field](/docs/assets/brickworks/schema-field-types#jinjava-code) in the record. Use it to pass:

- product identifiers for catalog lookups
- user session data for personalization from external systems
- external system identifiers

**Referencing `context` in a Jinjava field**

In any Jinjava field expression, you can read `context` values using dot notation. Nested objects are supported:

- `{{ context.itemId }}` — reads a top-level value
- `{{ context.catalog.itemId }}` — reads a nested value

For example, if you pass the following in the request:


<pre><code class="language-json">{
  "context": {
    "catalog": { "itemId": "sku-123" }
  }
}</code></pre>


A Jinjava field with the expression `{{ context.catalog.itemId }}` renders `sku-123`.

You can also define context [while previewing records](/docs/assets/brickworks/quick-start/creating-a-record#additional-preview-context-parameters).

### `fieldContext`

`fieldContext` passes parameters directly to individual fields during generation. Each top-level key is the **API name** of a schema field, and everything nested under it is scoped exclusively to that field — not shared with any other field in the record.

Use it to:

- override [Synerise object](/docs/assets/brickworks/synerise-objects) configuration per request
- provide field-specific external data parameters
- control the processing behavior for specific fields

The accepted parameters depend on the field type. Supported for:

**[One-to-many relation](/docs/assets/brickworks/schema-field-types#one-to-many)** — `page` and `limit` for pagination:


<pre><code class="language-json">{
  "fieldContext": {
    "oneToManyRelation": {
      "page": 2,
      "limit": 5
    }
  }
}</code></pre>


**[AI recommendation](/docs/assets/brickworks/synerise-objects#ai-recommendation)** — any parameter accepted by the [recommendations API](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#tag/Recommendations/operation/GetRecommendationsByCampaignV2):


<pre><code class="language-json">{
  "fieldContext": {
    "similarProducts": {
      "itemId": "c8a42eb1-2582-403e-8497-976f28b479ee",
      "additionalFilter": "brand == TEST"
    }
  }
}</code></pre>


where `similarProducts` is the API name of the recommendation field.

#### Using Jinjava expressions with `fieldContext`

Recommendation fields allow you to configure each parameter — for example, `itemId` — as a [Jinjava field](/docs/assets/brickworks/schema-field-types#jinjava-code). This means the parameter's value is not hardcoded: instead, it is evaluated from a Jinjava expression at generation time.

A common pattern is to read the value from `context`. For example, setting the `itemId` parameter to the expression `{{ context.catalog.itemId }}` means that when the record is generated, Brickworks evaluates the expression and uses the result as `itemId` for the recommendation.

When you additionally pass `fieldContext` for that parameter, the following priority applies:

- **`fieldContext` provided** — the value from `fieldContext` is used directly. The Jinjava expression is not evaluated.
- **`fieldContext` not provided** — the Jinjava expression is evaluated against `context`.

This gives you a flexible pattern: use `context` as the default data source via Jinjava expressions in the schema, and override specific recommendation parameters per request using `fieldContext`.

**Example**: the `recoField` field has its `itemId` parameter configured as a Jinjava field with expression `{{ context.catalog.itemId }}`.


<div class="content-tabs" data-tab-group="tabgrp-1252">
<div class="tab-buttons"><button class="tab-button" data-tab-id="tabgrp-1252-0" data-tab-group="tabgrp-1252" data-tab-active="true">fieldContext provided — takes priority</button><button class="tab-button" data-tab-id="tabgrp-1252-1" data-tab-group="tabgrp-1252">fieldContext not provided — resolved from context</button></div>

<div class="tab-panel" data-tab-id="tabgrp-1252-0" data-tab-group="tabgrp-1252" data-tab-active="true">

<pre><code class="language-json">{
  "context": {
    "catalog": { "itemId": "sku" }
  },
  "fieldContext": {
    "recoField": {
      "itemId": "e579487933852f3a83abd9e840175c"
    }
  }
}</code></pre>


`itemId` resolves to `e579487933852f3a83abd9e840175c` — taken from `fieldContext`.

</div>

<div class="tab-panel" data-tab-id="tabgrp-1252-1" data-tab-group="tabgrp-1252">

<pre><code class="language-json">{
  "context": {
    "catalog": { "itemId": "sku" }
  },
  "fieldContext": {}
}</code></pre>


`itemId` resolves to `sku` — evaluated from `{{ context.catalog.itemId }}`.

</div>
</div>




## Methods of displaying records

### API

**Authentication**:
When generating content from a record, you can authenticate as a:
- workspace or Synerise user: in this case, you need to declare a profile for context.
- profile: in this case, the profile is the context.

  **Example**:
  In the following example, content is generated for the following record:
  <figure><img src="/api/docs/image/54176ad07f146575310749eba44b7c2f42c1b327/docs/assets/brickworks/_gfx/brickworks-example-record-generation.png" class="medium" alt="Example record with a Jinjava code field"><figcaption>Example record with a <a href="/docs/assets/brickworks/schema-field-types#jinjava-code">Jinjava code field</a></figcaption></figure>

  To generate content, make the following request:

  <pre><code class="language-plaintext">curl --location 'https://api.synerise.com/brickworks/v1/schemas/docsSchema/records/docsRecord/generate' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer eyJhbGciINVALIDDUm_1Vivk' \
  --data '{
    "context": {
        "dayOfWeek": "Monday"
    }
  }'</code></pre>


  where:
- `docsSchema` is the API name of the schema.
- `docsRecord` is the slug of the record.  
    In singleton schemas, use the API name (`appName`) or UUID of the schema in place of the record identifier.
- `Bearer ...` is a profile JWT.  
  This identifies the profile whose data is used for the `{% customer firstname %}` insert.
  It would also provide data for other elements with a profile context (for example, a recommendation), if the record included them.
- `context.dayOfWeek` provides the value for the `{{ context.dayOfWeek }}` insert in the record.

For more details on the request parameters, see the [API reference](https://developers.synerise.com/Brickworks/Brickworks.html#tag/Brickworks:-Content-generation).

The response is:

<div class="highlight-code-block" data-hl-lines="7">
<pre><code class="language-json">{
    "__slug": "docsRecord",
    "__recordVersion": 1,
    "__publishedAt": "2025-12-11T16:58:55.101836Z",
    "__updatedAt": "2025-12-11T16:58:55.092stipZ",
    "__createdAt": "2025-12-05T12:49:04.870298Z",
    "exampleJinjava": "Hello Tom!\nIt's Monday.",
    "__schemaId": "c8e842bc-1580-4272-a98d-f3dc79542bb1",
    "__id": "e7635a46-d460-43b5-a878-6a2f9dd16295",
    "__schemaVersion": 1
}</code></pre>
</div>


where `exampleJinjava` is the API name of the field in the record, and the value is the processed content.

The parameters which start with `__` are the metadata of the record. Their descriptions are available in the [API reference](https://developers.synerise.com/Brickworks/Brickworks.html#tag/Brickworks:-Content-generation).


### Mobile SDK

You can use the `generateBrickworks` method. See the Mobile SDK reference:
- [Android](/developers/mobile-sdk/method-reference/android/content#generate-brickworks)
- [iOS](/developers/mobile-sdk/method-reference/ios/content#generate-brickworks)
- [Flutter](/developers/mobile-sdk/method-reference/flutter/content#generate-brickworks)
- [React Native](/developers/mobile-sdk/method-reference/react-native/content#generate-brickworks)

### In-app

You can use Jinjava tags or the [`SRInApp.internalMethod("Content/generateBrickworks")` method](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#use-a-mobile-sdk-method) from the in-app JS SDK.

### Jinjava tags

Use Brickworks content in templates across the Synerise platform with dedicated JinJava tags.


JinJava tags work consistently across all Synerise modules that support JinJava rendering, creating a unified content experience throughout your platform:

- **Experience Hub channels** – Email campaigns, SMS messaging, mobile push notifications, and web push notifications with dynamic, personalized content 
- **Automation Hub workflows** – Sophisticated automation sequences with content that adapts based on customer actions and behavioral triggers 
- **Screen views and Documents** – Interactive displays, personalized mobile applications content
- **In-App Messaging**– Contextual experiences that respond to customer behavior in real-time

#### Generate record

This tag can't be used in Brickworks schemas or records. In Documents and Screen Views, if you want to display an entire object instead of just one property, you need to use `{{ brickworks_result|tojson }}`

In singleton schemas, use the API name (`appName`) or UUID of the schema in place of the record identifier.

The `brickworksgenerate` tag generates a an object from a record with all references resolved and Jinja templates rendered:

    
<pre><code class="language-jinja">{% set myFieldContext = {"oneToManyRelation": {"page":2, "limit": 50}} %}
{% set myContext={
    "example1":"value1",
    "example2":"value2"
    } 
%}

{% brickworksgenerate schemaId=SCHEMA_ID/APP_ID recordId=RECORD_ID/SLUG context=myContext fieldContext=myFieldContext %}</code></pre>


where:
- The values for the `context` and `fieldContext` arguments must be variables created with `set` (as shown above).
- `myFieldContext` provides paging data for a relation field named `oneToManyRelation`. You can skip this argument if you don't need it.
- `myContext` provides values for two inserts used in the record (regardless of field names): `{{ context.example1 }}` and `{{ context.example2 }}`. You can skip this argument if you don't need it.

Alternatively, you can use `brickworksgeneratevar` to create a `{{ brickworks_result }}` variable for reuse in a template:  


<pre><code class="language-jinja">{% brickworksgeneratevar schemaId=SCHEMA_ID/APP_ID recordId=RECORD_ID/SLUG context=myContext fieldContext=myFieldContext %}
  {{ brickworks_result }}            {# prints out the entire record #}
  {{ brickworks_result.someString }} {# prints out the value of the someString field #}
{% endbrickworksgeneratevar %}</code></pre>


#### Fetch raw record

This tag can't be used in Brickworks schemas or records. In Documents and Screen Views, if you want to display an entire object instead of just one property, you need to use `{{ brickworks_result|tojson }}`

In singleton schemas, use the API name (`appName`) or UUID of the schema in place of the record identifier.

- The following tag fetches a raw record as defined in the database: 
    
  <pre><code class="language-jinja">{% brickworks schemaId=SCHEMA_ID/APP_ID recordId=OBJECT_ID/SLUG %}</code></pre>
  
- The following tag fetches a raw record as defined in the database, but saves the result to a variable for reuse in your template:  
    
  <pre><code class="language-jinja">{% brickworksvar schemaId=SCHEMA_ID/APP_ID recordId=OBJECT_ID/SLUG %}
    {{ brickworks_result }}
  {% endbrickworksvar %}</code></pre>


#### Fetch raw records

This tag lets you retrieve multiple records (raw content) from a schema and access the result as an iterable.

This tag can't be used in Brickworks schemas or records. In Documents and Screen Views, if you want to display an entire object instead of just one property, you need to use `{{ brickworks_result|tojson }}`


<pre><code class="language-jinja">{% brickworksrecordsvar schemaId=ID/APPID [optional parameters] %}

{# example logic: iterate through result and return record IDs #}
{% for record in brickworks_result %}
{{ record.id }} 
{% endfor %}
{# end example logic #}
{% endbrickworksrecordsvar %}</code></pre>


where:
- `schemaId` is the App ID or UUID of a schema.
- `optional parameters` can be used to sort and filter the retrieved records:
    - The parameters can be applied in two ways (see [examples](#filtering-examples)):
        - as arguments in the tag.  
            In this case, `slugs`, `ids`, and `filters` must be declared with `set` first.
        - as a `filteringParams` object. If you insert the same parameter in both ways, `filteringParams` takes precedence.
    - You can use these parameters: 
        - `sortBy`: a record attribute to sort by and the sorting direction.  
            **This parameter can't be added to `filteringParams`**  
            For a list of sorting attributes, see the [/v1/schemas/{schemaIdentifier}/records (Get records) endpoint](https://developers.synerise.com/Brickworks/Brickworks.html#tag/Brickworks:-Records/operation/getRecordsFromSchema).
        - `search`: a string to search for in the values of fields which are [configured as searchable in the schema](/docs/assets/brickworks/schema-field-types#common-field-properties).
        - `filters`: an RSQL string to filter the records.  
          These following system parameter names must include the `__` prefix: `__id`, `__schemaId`, `__name`, `__slug`, `__status`, `__createdAt`, `__updatedAt`, `__publishedAt`, `__recordVersion`
        - `slugs`: a list of record slugs. Looks for exact matches.
        - `ids`: a list of record IDs. Looks for exact matches.

<span id="filtering-examples"></span>

<div class="content-tabs" data-tab-group="tabgrp-1253">
<div class="tab-buttons"><button class="tab-button" data-tab-id="tabgrp-1253-0" data-tab-group="tabgrp-1253" data-tab-active="true">filteringParams</button><button class="tab-button" data-tab-id="tabgrp-1253-1" data-tab-group="tabgrp-1253">Arguments</button></div>

<div class="tab-panel" data-tab-id="tabgrp-1253-0" data-tab-group="tabgrp-1253" data-tab-active="true">

You can collect the filters in an object and provide that object as an argument in the tag.  
Example:

<pre><code class="language-jinja">{% set parametersVar = {
    search: "string",
    filters: "status==PUBLISHED",
    slugs: ["string","string"],
    ids: ["uuid","uuid"]
} %}
{% brickworksrecordsvar
    schemaId=string
    filteringParams=parametersVar %}
{{ brickworks_result }}
{% endbrickworksrecordsvar %}</code></pre>

</div>

<div class="tab-panel" data-tab-id="tabgrp-1253-1" data-tab-group="tabgrp-1253">

You can enter the filters as arguments of the tag. Some of them must first be declared as variables with `set`, as shown in the example:

<pre><code class="language-jinja">{% set filtersVar = "status==PUBLISHED" %}
{% set slugsVar = ["string","string"] %}
{% set idsVar = ["uuid","uuid"] %}
{% brickworksrecordsvar 
    schemaId=string
    search=string
    sortBy=createdAt:asc
    filters=filtersVar
    slugs=slugsVar
    ids=idsVar
%}
{{ brickworks_result }}
{% endbrickworksrecordsvar %}</code></pre>

</div>
</div>

