# Create Contact

`POST https://api.inboxjot.com/v1/contacts`

Creates a contact, or updates the contact with the same address. The API answers 201 for a new contact and 200 for an existing one. A new contact is subscribed unless you send `subscribed: false`. Needs a Full key. A key limited to one domain answers 403. Send an optional `Idempotency-Key` header to retry safely. See Idempotency.

## Body Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | string | Yes | The contact address, up to 320 characters. Invalid and disposable addresses are refused. |
| `first_name` | string \| null | No | First name, up to 200 characters. Send `null` to clear it. |
| `last_name` | string \| null | No | Last name, up to 200 characters. Send `null` to clear it. |
| `language` | string \| null | No | A language code, such as `en` or `pt-BR`. |
| `notes` | string \| null | No | Private notes, up to 5,000 characters. Send `null` to clear them. |
| `properties` | object \| null | No | Values for properties you added in Settings, keyed by the property key. Each value must match the property type: text up to 2,000 characters, a number, `true` or `false`, a date, or one of a choice property’s options. `null` clears a value. The values merge with the ones the contact has. |
| `subscribed` | boolean \| null | No | A new contact is subscribed. Send `false` to unsubscribe the contact from all email. Leave it out to keep the status of an existing contact. |
| `segment_ids` | string[] \| null | No | Static segments to add the contact to, up to 50. Each one must exist. |

## Response

The contact as Retrieve Contact returns it, with a `created` field.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | No | The contact id. |
| `email` | string | No | The contact address. |
| `first_name` | string \| null | No | First name. |
| `last_name` | string \| null | No | Last name. |
| `status` | string | No | One of `subscribed`, `pending` or `unsubscribed`. |
| `language` | string | No | Language code. |
| `properties` | object | No | Property values, keyed by the property key. |
| `segments` | object[] | No | The segments the contact is in. |
| `segments[].id` | string | No | The segment id. |
| `segments[].name` | string | No | The segment name. |
| `topics` | object[] | No | Every topic in the workspace, with the contact’s choice. |
| `topics[].id` | string | No | The topic id. |
| `topics[].name` | string | No | The topic name. |
| `topics[].status` | string \| null | No | The contact’s choice: `subscribed`, `pending` or `unsubscribed`. `null` when the contact has not chosen. |
| `topics[].subscribed` | boolean | No | Whether the contact gets email for this topic, counting the topic default. |
| `created_at` | string | No | ISO 8601 time. |
| `updated_at` | string | No | ISO 8601 time. |
| `created` | boolean | No | True when the contact is new. |

## Request

cURL:

```bash
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"
    }
  }'
```

Node.js:

```javascript
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"},
    }
)
```

## Responses

| Status | Description |
| --- | --- |
| 200 | Updated the contact that has this email address. |
| 201 | Created a new contact. |
| 400 | A field is missing or invalid, or the Idempotency-Key header is not valid. |
| 401 | The API key is missing, revoked or expired. |
| 403 | The key is a Sending key or is limited to one domain, or the request comes from outside its IP allowlist. |
| 409 | A request with the same Idempotency-Key is still running. Retry after one second. |
| 413 | The body is larger than 2 MB. |
| 415 | The Content-Type header is not application/json. |
| 422 | The Idempotency-Key was already used with a different request. |
| 429 | Too many requests for this key. Wait for the seconds in the Retry-After header. |
| 500 | Something failed on our side. Retry later. |

200:

```json
{
  "id": "con_06d2mfk8r9wq3zh5ka2pe",
  "email": "sukhamoy@example.com",
  "first_name": "Sukha",
  "last_name": "Moy",
  "status": "subscribed",
  "language": "en",
  "properties": {
    "plan": "pro"
  },
  "segments": [
    {
      "id": "seg_06d2mfk8r2kd7fq4mx9ab",
      "name": "Customers"
    }
  ],
  "topics": [
    {
      "id": "top_06d2mfk8r6pn2tc8yw3hd",
      "name": "Product Updates",
      "status": "subscribed",
      "subscribed": true
    }
  ],
  "created_at": "2026-10-12T09:41:07.000Z",
  "updated_at": "2026-10-15T14:02:33.000Z",
  "created": false
}
```

201:

```json
{
  "id": "con_06d2mfk8r9wq3zh5ka2pe",
  "email": "sukhamoy@example.com",
  "first_name": "Sukha",
  "last_name": "Moy",
  "status": "subscribed",
  "language": "en",
  "properties": {
    "plan": "pro"
  },
  "segments": [
    {
      "id": "seg_06d2mfk8r2kd7fq4mx9ab",
      "name": "Customers"
    }
  ],
  "topics": [
    {
      "id": "top_06d2mfk8r6pn2tc8yw3hd",
      "name": "Product Updates",
      "status": "subscribed",
      "subscribed": true
    }
  ],
  "created_at": "2026-10-12T09:41:07.000Z",
  "updated_at": "2026-10-15T14:02:33.000Z",
  "created": true
}
```

400:

```json
{
  "name": "validation_error",
  "status": 400,
  "message": "The request body is not valid JSON",
  "errors": [
    {
      "message": "The request body is not valid JSON",
      "location": "body"
    }
  ],
  "request_id": "5f0c6a2e-8d1b-4c7a-9e3f-2b6d4a1c8e90"
}
```

401:

```json
{
  "name": "unauthorized",
  "status": 401,
  "message": "Unauthorized",
  "errors": [],
  "request_id": "5f0c6a2e-8d1b-4c7a-9e3f-2b6d4a1c8e90"
}
```

403:

```json
{
  "name": "forbidden",
  "status": 403,
  "message": "This key can only send email",
  "errors": [],
  "request_id": "5f0c6a2e-8d1b-4c7a-9e3f-2b6d4a1c8e90"
}
```

409:

```json
{
  "name": "concurrent_idempotent_requests",
  "status": 409,
  "message": "A request with this idempotency key is still in progress. Try again later.",
  "errors": [],
  "request_id": "5f0c6a2e-8d1b-4c7a-9e3f-2b6d4a1c8e90"
}
```

413:

```json
{
  "name": "payload_too_large",
  "status": 413,
  "message": "The request body is too large",
  "errors": [],
  "request_id": "5f0c6a2e-8d1b-4c7a-9e3f-2b6d4a1c8e90"
}
```

415:

```json
{
  "name": "unsupported_media_type",
  "status": 415,
  "message": "The Content-Type must be application/json",
  "errors": [],
  "request_id": "5f0c6a2e-8d1b-4c7a-9e3f-2b6d4a1c8e90"
}
```

422:

```json
{
  "name": "invalid_idempotent_request",
  "status": 422,
  "message": "This idempotency key was already used with a different request",
  "errors": [],
  "request_id": "5f0c6a2e-8d1b-4c7a-9e3f-2b6d4a1c8e90"
}
```

429:

```json
{
  "name": "rate_limit_exceeded",
  "status": 429,
  "message": "Too many attempts. Try again later.",
  "errors": [],
  "request_id": "5f0c6a2e-8d1b-4c7a-9e3f-2b6d4a1c8e90"
}
```

500:

```json
{
  "name": "unknown_error",
  "status": 500,
  "message": "Something went wrong. Please try again later.",
  "errors": [],
  "request_id": "5f0c6a2e-8d1b-4c7a-9e3f-2b6d4a1c8e90"
}
```
