# Create contact

> Create one contact.

Source: https://sndr.sh/docs/api/contacts/create-contact

`POST https://api.sndr.sh/v1/contacts`

Create one contact. Returns 201 with the contact, or 409 if the email already exists — use POST /contacts/bulk to upsert.

Scope: `send`

**Body** (JSON)

- `email` (string, required): Email address. Stored lowercase and unique per account.
- `first_name` (string): First name, max 100 characters.
- `last_name` (string): Last name, max 100 characters.
- `status` (string): subscribed (default), unsubscribed, bounced or complained. Only subscribed contacts receive broadcasts.
- `attributes` (object): Free-form key-value data, e.g. {"plan":"pro"}.
- `source` (string): Label for where the contact came from. Defaults to manual.
- `group_ids` (string[]): Groups (grp_...) to add the new contact to. Unknown IDs are ignored.

**Request**

```bash
curl -X POST 'https://api.sndr.sh/v1/contacts' \
  -H "Authorization: Bearer $SNDR_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "email":      "jane@example.com",
    "first_name": "Jane",
    "last_name":  "Doe",
    "attributes": { "plan": "pro", "city": "Berlin" },
    "source":     "checkout",
    "group_ids":  ["grp_4d8a0c5e-1f7"]
  }'
```

**Response** (201)

```json
{
  "id":              "con_0e6b7f21-c58",
  "organization_id": "org_8d41c7a2-3f6",
  "email":           "jane@example.com",
  "first_name":      "Jane",
  "last_name":       "Doe",
  "attributes":      { "plan": "pro", "city": "Berlin" },
  "status":          "subscribed",
  "source":          "checkout",
  "created_at":      "2026-06-01T12:00:00Z",
  "updated_at":      "2026-06-01T12:00:00Z"
}
```

**Errors**

- `unauthenticated` (401): Missing or invalid API key.
- `invalid_request` (400): Body is not valid JSON, has an unknown field, or a field has the wrong type.
- `insufficient_scope` (403): The API key is missing the send scope.
- `conflict` (409): A contact with this email already exists.
- `validation_failed` (422): email is missing or invalid, a name is over 100 characters, or status is not one of the four values.
