Skip to the documentation
API

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`.

POSTapi.openemail.uk/contacts

Runs the real call against your workspace, with your own key.

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": "[email protected]",  "name": "Grace Hopper",  "notes": "Met at the compiler workshop"}'
Response
{  "object": "contact",  "email": "[email protected]",  "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.