# Contacts

A contact is a person you send marketing email to. Each contact has an email address, a status and any properties you define. The contacts API needs a key with Full access.

## Create or Update a Contact

`POST /v1/contacts` creates the contact, or updates it when the email already exists. It answers `201` for a new contact and `200` for an update.

```bash cURL
curl -X POST https://api.inboxjot.com/v1/contacts \
  -H "Authorization: Bearer $INBOXJOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "sukhamoy@example.com",
    "first_name": "Sukha",
    "last_name": "Moy",
    "properties": { "plan": "pro" }
  }'
```

```javascript Node.js
import { Inboxjot } from 'inboxjot';

const inboxjot = new Inboxjot();

const contact = await inboxjot.contacts.create({
  email: 'sukhamoy@example.com',
  first_name: 'Sukha',
  last_name: 'Moy',
  properties: { plan: 'pro' },
});
```

```rust Rust
use inboxjot::{CreateContact, Inboxjot};
use serde_json::json;

let client = Inboxjot::from_env()?;

let contact = client
    .contacts()
    .create(&CreateContact {
        email: "sukhamoy@example.com".into(),
        first_name: Some("Sukha".into()),
        last_name: Some("Moy".into()),
        properties: json!({ "plan": "pro" }).as_object().cloned(),
        ..Default::default()
    })
    .await?;
```

```go Go
client := inboxjot.NewClient("")

contact, err := client.Contacts.Create(ctx, inboxjot.CreateContactParams{
	Email:      "sukhamoy@example.com",
	FirstName:  inboxjot.Value("Sukha"),
	LastName:   inboxjot.Value("Moy"),
	Properties: map[string]any{"plan": "pro"},
})
```

```python Python
from inboxjot import Inboxjot

inboxjot = Inboxjot()

contact = inboxjot.contacts.create(
    {
        "email": "sukhamoy@example.com",
        "first_name": "Sukha",
        "last_name": "Moy",
        "properties": {"plan": "pro"},
    }
)
```

| Field                 | Description                                                            |
| --------------------- | ---------------------------------------------------------------------- |
| email                 | Required. Up to 320 characters.                                        |
| first_name, last_name | Up to 200 characters. Send null to clear.                              |
| language              | A code such as en or pt-BR.                                            |
| notes                 | Up to 5,000 characters.                                                |
| properties            | Values for properties you defined. New values merge with the old ones. |
| subscribed            | Sets the status. A new contact from the API is subscribed by default.  |
| segment_ids           | Up to 50 static segments.                                              |

## Read and Delete

`GET`, `PATCH` and `DELETE /v1/contacts/{contact_id}` take the contact id or the email address. `GET` returns the contact with its segments and topics. `PATCH` also takes `topics`, a list of topic ids with a status.

```bash cURL
curl https://api.inboxjot.com/v1/contacts/sukhamoy@example.com \
  -H "Authorization: Bearer $INBOXJOT_API_KEY"

curl -X DELETE https://api.inboxjot.com/v1/contacts/sukhamoy@example.com \
  -H "Authorization: Bearer $INBOXJOT_API_KEY"
```

```javascript Node.js
import { Inboxjot } from 'inboxjot';

const inboxjot = new Inboxjot();

const contact = await inboxjot.contacts.get('sukhamoy@example.com');

await inboxjot.contacts.delete('sukhamoy@example.com');
```

```rust Rust
use inboxjot::Inboxjot;

let client = Inboxjot::from_env()?;

let contact = client.contacts().get("sukhamoy@example.com").await?;

client.contacts().delete("sukhamoy@example.com").await?;
```

```go Go
client := inboxjot.NewClient("")

contact, err := client.Contacts.Get(ctx, "sukhamoy@example.com")

result, err := client.Contacts.Delete(ctx, "sukhamoy@example.com")
```

```python Python
from inboxjot import Inboxjot

inboxjot = Inboxjot()

contact = inboxjot.contacts.get("sukhamoy@example.com")

inboxjot.contacts.delete("sukhamoy@example.com")
```

> Sending segment_ids in a PATCH replaces the static segments of the contact.
> The API cannot subscribe a contact to a topic they unsubscribed from. A delete
> or an erase keeps the contact's opt-outs. If you add the address again, it
> comes back unsubscribed from all email or from the topics it left.

## Properties

Define custom properties in Contacts › Properties before you send them. A property has a type: Text, Number, Date, True or false, or Choice. Its key starts with a letter and uses lowercase letters, numbers and underscores. You cannot change the key later.

## Import a CSV

Click Import Contacts to upload a CSV of up to 100 MB. The first row names the columns. Match each column to email, a name field or a property, or skip it. One column must be the email.

You can add the contacts to a static segment and subscribe them to a topic. A topic needs you to confirm that the contacts gave consent. Without a topic, new contacts are saved as not subscribed.

## Statuses

| Status         | Meaning                                                                                      |
| -------------- | -------------------------------------------------------------------------------------------- |
| subscribed     | Gets campaigns and automation emails.                                                        |
| pending        | Shown as Not Confirmed. Waits for a double opt-in confirmation.                              |
| not_subscribed | Never gave consent, such as a contact you imported without a topic. Gets no marketing email. |
| unsubscribed   | Opted out. Gets no marketing email.                                                          |

A bounce adds the address to the suppression list and does not change the status. A complaint adds it to the suppression list and also unsubscribes the contact from all email. Only the contact can lift a complaint, by resubscribing from the preference page or a confirmation link.
