This page says what a binding means: which data each namespace reads, when a placeholder needs `arrayPath`, what an Area loop's `target` and `count` resolve to, and which compiler functions exist. The tool descriptions do not have room for it.

For how a person picks the same values, see [Placeholder Syntax](/docs/buttons/interface-button/interface-builder/reference/data-binding/placeholder-syntax) and [Data Picker](/docs/buttons/interface-button/interface-builder/reference/data-binding/data-picker).

## How a Binding Is Written

A field that carries data is a plain string with placeholder tokens in it. Text and tokens mix freely:

```text
Deal: {{key: 'title', name: 'Title', resource: 'deal', variableType:'normal'}} is open
```

- Never write a token yourself. Call `list_bindable_values` to find a `key`, then call `make_placeholder` with the `namespace` and the `key`. Put the token it returns into the string.
- `make_placeholder` derives the display name, and for a variable its id and confidentiality. A token it returns always points at something that exists at that moment.
- `get_block` returns every Data picker field as the same plain string, so you read the form you write.
- Every string of a block is searched for tokens when the view renders, so a token resolves in any field. A missing value resolves to an empty string. `get_block` lists the tokens that no longer point at anything in `brokenBindings`.

## Namespaces

`namespace` is the `resource` of the token. There are ten.

| Namespace | What it reads | `key` is |
|---|---|---|
| `deal` | The Pipedrive deal the view opens on. In the builder, the deal sample. | A path in the deal object, such as `title` or `org_id.name`. A custom field is its hash key. |
| `organization` | The Pipedrive organization the view opens on. In the builder, the organization sample. | A path in the organization object. |
| `person` | The Pipedrive person the view opens on. In the builder, the person sample. | A path in the person object. |
| `user` | The Pipedrive user who opens the view. | A path in the user object. |
| `custom` | The response of the view's data source URL. In the builder, the view's Sample data. | A path in that response. |
| `variable` | A variable of the button. | The variable's `key`. The token stores the variable's id, so renaming the key does not break it. |
| `view` | A View reference: another view of the same button. | The view's id. It resolves to that id. |
| `system` | Where the view runs: `resource_id`, `resource`, `company_id` and `user_id`. | One of those four names. |
| `searchparams` | The URL parameters the view was opened with. | The parameter name. |
| `functions` | A keyword of the Functions tab. See [Keywords](#keywords). | The keyword. |

Notes on the namespaces:

- **The four Pipedrive namespaces.** `deal`, `organization` and `person` are empty on a floating window button, because its views get no Pipedrive record. `list_bindable_values` gives each key a `label`: a custom field's own name where the field has one.
- **Paths go through objects.** A related record's value, such as `org_id.name`, and a custom field under `custom_fields` exist only further down the tree. Give `list_bindable_values` a `prefix` to walk into them.
- **`variable`.** A confidential variable resolves in the browser only as the token itself, never as its value. `list_bindable_values` lists confidential variables too, by key. No value travels, `include_values` included.
- **`view`.** In the builder, the Preview and the Test view, a reference to a deleted view resolves to an empty string. The rendered view cannot tell, and it returns the id.
- **`system`.** On a floating window button, `resource_id` and `resource` are empty and `list_bindable_values` does not offer them. `company_id` and `user_id` come from the session and are always there.
- **`searchparams`.** The builder has no URL parameters, so `list_bindable_values` returns nothing for it. You must be told the name of a parameter to bind it.
- **`functions`.** `list_bindable_values` does not take this namespace. Name the keyword with `make_placeholder` and `variableType`.

## Example Values

`list_bindable_values` lists keys and no values. Pass `include_values: true` and each listed value carries a `value` as well: what the key holds in one real record, cut at 40 characters, an array shown as its item count and an object shown as nothing, exactly as the Data picker draws it beside the key. Ask for it when you have to choose between keys that look alike, not to read a record — a listing can run to hundreds of keys.

Where the values come from:

- `deal`, `organization` and `person` read the **Preview record**, the record the Preview and the Test view run against. Asking for values fetches it; asking for keys alone fetches nothing.
- `custom` reads the view's Sample data, `variable` a variable's own value and `system` the four values a run would actually send. All three are in the browser already.
- The `user` namespace carries no value at all, and the sandbox user behind `owner_id` and `creator_user_id` supplies none anywhere: a value at those keys inside a deal, an organization or a person is shown only where the fetch supplied one.
- A confidential variable carries no value, whoever asks.
- `view` and `searchparams` have no values of their own.

A namespace with no record — one the Preview record does not reach, a record that was not found, a failed fetch, or a button that carries no Pipedrive record at all — lists its keys unchanged and says why once in `valuesUnavailable`. A namespace that does have values names the record in `valuesFrom`. The values are display only: a placeholder carries the key and resolves against whatever record the run carries.

## When `arrayPath` Is Required

A key names the keys of an array's **item**, never an index. `list_bindable_values` walks into an array through its first item, so under `deal_products` it lists `deal_products.name`.

Such a key is not a path in the resource: the resource holds an array at `deal_products`, not an object. The token must therefore say which array it reads the key out of. Give `arrayPath` when a key goes through an array:

| Key | `arrayPath` |
|---|---|
| `title` | _(leave out)_ |
| `org_id.name` | _(leave out — `org_id` is an object)_ |
| `deal_products.name` | `deal_products` |

`make_placeholder` checks the key through the array's first item. If you leave out `arrayPath` for a key under an array, it refuses with `field_not_found` and names the array to give.

What the token resolves to depends on where the block is:

- **Outside an Area loop and outside a table,** the token resolves to a JSON array of that key's value in every item, such as `["Product A","Product B"]`. Empty values are left out.
- **Inside an Area loop in array mode,** the loop's target array wins over the token's `arrayPath`. A key that starts with the target's key is read out of the current item. See [Area Loops](#area-loops).
- **Inside a Table block's columns,** a key that starts with the table's target key is read out of the current row's item, the same way.

A token whose key does not start with the loop's or the table's target key resolves against the whole resource by its key alone. Its `arrayPath` is ignored there, so a key under another array resolves to an empty string, not to the JSON array it gives outside.

## Area Loops

An Area's `loop` has `enabled`, `mode`, `target` and `count`. Write `target` and `count` as strings with a token in them, the same way as any field. A loop that is not `enabled` does nothing.

### `target` (array mode)

- The loop reads the **first** token of `target`: its namespace and its `key`. The array is the value at that key in that namespace, for example `deal_products` in `deal`.
- If that value is not an array, or the array is empty, the area's rows are removed from the view.
- Otherwise the area's rows repeat once for each item, up to 1000 items. Items beyond that are dropped.
- Inside the rows, a key that starts with the target's key reads the current item. Write the key as `list_bindable_values` gives it, such as `deal_products.name`, with `arrayPath: 'deal_products'`.

### `count` (count mode)

- The loop resolves the tokens of `count` and reads the result as a number. Plain text such as `3` works too.
- If the result is not a number, or it is `0`, the area's rows are removed from the view.
- The number is rounded up (towards positive infinity), then its sign is dropped: `2.5` gives 3 repeats, `-2` gives 2, `-2.5` gives 2.
- The rows repeat up to 1000 times. Repeats beyond that are dropped.
- Compiler functions do not run in `count`. Write a placeholder or a plain number.

### The loop index

- In both modes, each repeat carries its number, starting from 1.
- Make its token with `make_placeholder` and `is_loop_index: true`. The key is `index`.
- The loop index resolves only in a block inside an Area loop. Anywhere else it resolves to nothing and `get_block` reports it broken.

### Other rules

- A loop whose area has conditional visibility on and whose condition resolves to empty or `false` does not repeat.
- Form inputs inside a loop submit under suffixed names (`name`, `name_loop_1`, …). See [Form Submission Types](/docs/buttons/interface-button/interface-builder/reference/data-binding/form-submission-types#forms-inside-a-looping-area).

## Compiler Functions

The Data picker's **Functions** tab offers the functions below. A function runs after the tokens in its arguments are substituted. Arguments are separated by `;`, and functions can be nested. The parameters, return values and examples of each function are in [Functions](/docs/buttons/interface-button/interface-builder/reference/data-binding/functions).

Write a function into a Data picker field as plain text and the tool stores the form that runs:

```
formatCurrency(fi-FI;EUR;{{key: 'value', name: 'Value', resource: 'deal', variableType:'normal'}})
```

`get_block` reads the field back as the same text, and the field opens in the builder as the chips a person's own insert produces. `list_functions` returns each function's parameter counts, parameters, return type and example as data.

**What counts as a function.** A name from the list below, spelled exactly, followed immediately by `(`, with balanced parentheses. A name that is unknown, wrongly cased or followed by a space stays text, so prose such as `Katso if (…)` is left alone. A `{{…}}` token is read whole, so a `)` or a `;` inside a display name counts for nothing. A `)` inside an argument is not supported — it ends the function, the same limit a person has.

**Where a function runs.** Only in a field that offers a Data picker. The schema `get_block_schema` returns marks each one with `dataPicker: true`. In any other field the text stays text.

**Three Area fields are the exception.** An Area loop reads its `target`, its `count` and its area's visibility condition before the functions of the view are run, so a function written in one of them is stored but never runs there. Write a placeholder or plain text in all three. An area's visibility condition does run its functions for showing and hiding the area — only the loop's own check reads it early. This is the behaviour a person's own insert has.

**What is refused.** A known name with unbalanced parentheses returns `function_unclosed`, and a parameter count outside the function's own bounds returns `function_arity` — for example `formatCurrency expects 3 parameters, got 2`. Both refuse the whole write and name the field, and nothing is written. Parameter types are not checked: a placeholder's value exists only at render.

| Category | Functions |
|---|---|
| Text Processing | `capFirst`, `capitalize`, `contains`, `endsWith`, `first`, `last`, `length`, `lower`, `replace`, `replaceAll`, `slice`, `split`, `startsWith`, `stripHtml`, `trim`, `upper` |
| Mathematics | `add`, `divide`, `multiply`, `round`, `subtract` |
| Logic & Comparison | `and`, `boolean`, `equals`, `gt`, `gte`, `if`, `lt`, `lte`, `not`, `notEquals`, `or`, `switch` |
| Data Validation | `isEmpty`, `isNotEmpty`, `isNumber`, `isWeekend`, `useDefault` |
| Date & Time | `addDays`, `addMonths`, `addYears`, `daysBetween`, `formatDate`, `formatDateTime`, `formatRelative`, `subtractDays`, `subtractMonths`, `subtractYears` |
| Data Manipulation | `formatCurrency`, `formatList`, `get`, `join`, `map`, `sort`, `sortBy`, `unique`, `uniqueBy` |

`boolean` is the one function whose truth test is not JavaScript's: it reads an empty array and an empty object as `false`, while `if`, `and`, `or` and `not` read them as true. Use `boolean` for a visibility condition that asks whether a list has anything in it.

A function's error shows when the view renders, not when you write the field.

### Keywords

The Functions tab also offers keywords. Make their tokens with `make_placeholder`, `variableType` and the keyword as the `key`. The namespace is always `functions`.

| `variableType` | Keyword | Resolves to |
|---|---|---|
| `systemFunc` | `now` | The current time as an ISO 8601 string. It works in a plain string. |
| `systemText` | `whitespace` | A space. |
| `systemText` | `emptystring` | An empty string. |
| `systemText` | `tab` | A tab character. |
| `systemText` | `newLine` | A line break. |

A `systemText` keyword takes effect only in the form a person's edit stores. In a plain string it stays as the token text. Unlike a compiler function, nothing converts it for you.
