# Contact properties

> Store extra data on contacts with default and custom properties, then use them to personalize campaigns.

Contact properties store additional information about your contacts that you can then use to personalize your [campaigns](https://www.senddart.com/docs/campaigns/managing). Alongside a set of default properties, you can define your own **custom properties**.

## Default properties

Every contact already carries these built-in properties:

- `first_name` — the contact’s first name.
- `last_name` — the contact’s last name.
- `email` — the contact’s email address.
- `unsubscribed` — whether the contact has unsubscribed from all campaigns.

## Custom properties

Create additional custom properties to store whatever you need — a company name, a plan tier, a signup source. Each property has a key, a value, and an optional fallback value.

**Property fields**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | Yes | The property name. Alphanumeric and underscores only, max 50 characters. Case-sensitive. |
| `type` | string | Yes | Either `string` or `number`. |
| `fallback_value` | string | number | No | Used for contacts that have no value set for this property. Must match `type`. |

**Node.js**

```js
import { SendDart } from 'senddart';

const mb = new SendDart('mb_xxxxxxxxx');

const { data, error } = await mb.contactProperties.create({
  "key": "company_name",
  "type": "string",
  "fallback_value": "Acme Corp"
});
console.log({ data, error });
```

**Ruby**

```ruby
require "senddart"

SendDart.api_key = "mb_xxxxxxxxx"

SendDart::ContactProperties.create({
  "key": "company_name",
  "type": "string",
  "fallback_value": "Acme Corp"
})
```

**PHP**

```php
<?php
require 'vendor/autoload.php';

use SendDart\SendDart;

$senddart = SendDart::client('mb_xxxxxxxxx');

$senddart->contactProperties->create([
  'key' => "company_name",
  'type' => "string",
  'fallback_value' => "Acme Corp"
]);
```

**Python**

```python
import senddart

senddart.api_key = "mb_xxxxxxxxx"

senddart.ContactProperties.create({
  "key": "company_name",
  "type": "string",
  "fallback_value": "Acme Corp"
})
```

**Go**

```go
import "github.com/shekhu10/senddart-sdks/senddart-go"

client := senddart.NewClient("mb_xxxxxxxxx")

property, err := client.ContactProperties.Create(&senddart.CreateContactPropertyRequest{
    Key:           "company_name",
    Type:          "string",
    FallbackValue: "Acme Corp",
})
```

**Rust**

```rust
use senddart::{ContactPropertyType, CreateContactPropertyOptions, SendDart};

let mb = SendDart::new("mb_xxxxxxxxx");

let params = CreateContactPropertyOptions::new(
    "company_name",
    ContactPropertyType::String,
)
.with_fallback_value(serde_json::json!("Acme Corp"));
let _property = mb.contact_properties.create(params).await?;
```

**Java**

```java
import com.senddart.SendDart;
import com.senddart.SendDartResponse;
import com.senddart.requests.CreateContactPropertyRequest;

SendDart senddart = new SendDart("mb_xxxxxxxxx");

CreateContactPropertyRequest request = CreateContactPropertyRequest.builder()
        .key("company_name")
        .type("string")
        .fallbackValue("Acme Corp")
        .build();

SendDartResponse response = senddart.contactProperties().create(request);
```

**.NET**

```csharp
using SendDart;

ISendDart senddart = SendDartClient.Create("mb_xxxxxxxxx");

var resp = await senddart.ContactPropertyCreateAsync(new ContactPropertyCreateOptions
{
    Key = "company_name",
    Type = "string",
    FallbackValue = "Acme Corp",
});
```

**cURL**

```bash
curl -X POST 'https://www.senddart.com/api/contact-properties' \
  -H 'Authorization: Bearer mb_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{
  "key": "company_name",
  "type": "string",
  "fallback_value": "Acme Corp"
}'
```

**CLI**

```bash
senddart contact-properties create \
  --key 'company_name' \
  --type 'string' \
  --fallback-value 'Acme Corp'
```

## Setting a value on a contact

A property’s fallback value is used for any contact that has no explicit value. To set a per-contact value, pass a `properties` object when you [create a contact](https://www.senddart.com/docs/api/contacts-create) or [update one](https://www.senddart.com/docs/api/contacts-update). You can update a contact by `id` or by `email`.

**cURL**

```bash
# Set a property while creating a contact
curl -X POST 'https://www.senddart.com/api/contacts' \
  -H 'Authorization: Bearer mb_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{
    "domain": "yourdomain.com",
    "email": "steve@example.com",
    "first_name": "Steve",
    "last_name": "Wozniak",
    "unsubscribed": false,
    "properties": { "company_name": "Acme Corp" }
  }'

# Or update an existing contact by email
curl -X PATCH 'https://www.senddart.com/api/contacts/steve@example.com' \
  -H 'Authorization: Bearer mb_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{ "properties": { "company_name": "Acme Corp" } }'
```

**Node.js**

```js
// Set a property while creating a contact
await fetch('https://www.senddart.com/api/contacts', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer mb_xxxxxxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    domain: 'yourdomain.com',
    email: 'steve@example.com',
    first_name: 'Steve',
    last_name: 'Wozniak',
    unsubscribed: false,
    properties: { company_name: 'Acme Corp' },
  }),
});

// Or update an existing contact by email
await fetch('https://www.senddart.com/api/contacts/steve@example.com', {
  method: 'PATCH',
  headers: {
    'Authorization': 'Bearer mb_xxxxxxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ properties: { company_name: 'Acme Corp' } }),
});
```

**Python**

```python
import requests

# Set a property while creating a contact
requests.post(
    "https://www.senddart.com/api/contacts",
    headers={"Authorization": "Bearer mb_xxxxxxxxx"},
    json={
        "domain": "yourdomain.com",
        "email": "steve@example.com",
        "first_name": "Steve",
        "last_name": "Wozniak",
        "unsubscribed": False,
        "properties": {"company_name": "Acme Corp"},
    },
)

# Or update an existing contact by email
requests.patch(
    "https://www.senddart.com/api/contacts/steve@example.com",
    headers={"Authorization": "Bearer mb_xxxxxxxxx"},
    json={"properties": {"company_name": "Acme Corp"}},
)
```

## Validation rules

A property is only applied to a contact if the property **key already exists** and the supplied value matches the property’s declared **type**. Otherwise the value is not set and the call fails with an error.

- **Unknown key** — if the property key does not exist, it is not added and the request fails.
- **Wrong type** — if the value’s type does not match the property’s `type`, it is not added and the request fails.
- **Case-sensitive keys** — `company_name`, `CompanyName`, and `company_Name` are three different keys. Match the key exactly.

> **Note:** List every property you have defined with [GET /contact-properties](https://www.senddart.com/docs/audiences/properties) to confirm the exact keys and types before setting values.

## Using properties in campaigns

Reference any property — default or custom — in your campaign HTML and text content to personalize each recipient’s message. Properties are resolved per-contact when the campaign is sent, using each contact’s value or the property’s fallback. You can also set this up when you [create a campaign](https://www.senddart.com/docs/api/campaigns-create) via the API.
