# Identity and permissions

TypeScript inputs, results, permissions and executable examples for identity and permissions.

Use this reference with the [complete developer tour](https://beepgrid.com/docs/sdks/typescript/tour.md) and [TypeScript types](https://beepgrid.com/docs/sdks/typescript/types.md). The example at the end runs after the tour setup.

## saveContactPermissions

Save the subject's dedicated contact defaults and exceptions atomically.

```text
saveContactPermissions(input: ContactPermissionsInput): Promise<unknown>
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `input` | `ContactPermissionsInput` (required) | Typed operation input. See its declaration in the language types reference. |

**Returns:** The saved policy and its new version.

**Permissions, lifecycle and errors:** Use the observed version and preserve deny effects. Explicit blocks override other matching grants; omission restores defaults.

Declared return type: `Promise<unknown>`.

[Working TypeScript example](https://beepgrid.com/docs/sdks/typescript/identity/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/typescript/types.md).

## Example

Run this region after [the shared setup](https://beepgrid.com/docs/sdks/typescript/tour.md). Assertions check the returned data; the full tour is a runnable program.



```typescript
const subject: Target = { kind: 'agent', id: builderId };
const contactPreview = readObject(await owner.previewContactPermissions({ subject }));
const contactVersion = Number(readObject(contactPreview.policy).version);
const contactPolicy = readObject(await owner.saveContactPermissions({subject, version: contactVersion,
  rules: [{action: 'view', target_kind: 'agent', target_id: billingId}]}));
assert.ok(Number(contactPolicy.version) > contactVersion);
```
