---
title: "Create a contact"
description: "Saves one address in the workspace address book. The address is the identity, so there is no id to choose and none in the response. It is trimmed and lowercased before it is stored, and the contact is saved with `source` set to `manual`. The new contact joins the built-in default audience as it is written, plus anything named in `audienceIds`."
url: "https://openemail.uk/docs/api/contacts/create"
area: "API"
category: "Mailbox"
---

# Create a contact

Saves one address in the workspace address book. The address is the identity, so there is no id to choose and none in the response. It is trimmed and lowercased before it is stored, and the contact is saved with `source` set to `manual`. The new contact joins the built-in default audience as it is written, plus anything named in `audienceIds`.

`POST /contacts`

## POST /contacts

Saves one address in the workspace address book. The address is the identity, so there is no id to choose and none in the response. It is trimmed and lowercased before it is stored, and the contact is saved with `source` set to `manual`. The new contact joins the built-in default audience as it is written, plus anything named in `audienceIds`.

## Example

Needs `contacts:write`. Sending `audienceIds` also needs `audiences:write`.

**curl**

```
curl -X POST "$OE/contacts" -H "$AUTH" -H 'content-type: application/json' -d '{
  "email": "grace@example.com",
  "name": "Grace Hopper",
  "notes": "Met at the compiler workshop"
}'
```

**Response**

```
{
  "object": "contact",
  "email": "grace@example.com",
  "name": "Grace Hopper",
  "source": "manual",
  "notes": "Met at the compiler workshop",
  "lastSeenAt": null,
  "createdAt": "2026-09-18T09:00:00.000Z",
  "updatedAt": "2026-09-18T09:00:00.000Z",
  "audiences": [
    { "id": "aud_9f2c4b7e1a0d63d84c5f2e7b", "name": "All contacts", "builtin": "default" }
  ]
}
```

> An address already in the book is a `409` `contact_exists` rather than a merge, so a retry cannot quietly overwrite a name somebody edited in the app. Read the row and PATCH it instead.

> `lastSeenAt` stays null until mail goes to the address from the app composer. `source` and `lastSeenAt` are the server’s and are not accepted in the body.

> An audience id in `audienceIds` that does not exist in this workspace is a `404` and nothing is written.
