---
title: "Create or update a contact"
method: POST
path: "/v1/contacts"
tags: ["contacts"]
---

# Create or update a contact

`POST /v1/contacts`

Gateway-native contact upsert (dual-writes the gateway ACL store and the assistant info mirror). Matches by id, then by any provided (type, address) channel, else creates.

## Request body

- object
  - `id` string — Existing contact id to update; omit to create or match by channel
  - `displayName` string, required — Required on every upsert, including updates by id
  - `notes` string, nullable
  - `contactType` string
  - `assistantMetadata` object — Required when contactType is 'assistant'
    - `species` string, required
    - `metadata` object, nullable
  - `channels` object[]
    - `type` string, required
    - `address` string, required
    - `isPrimary` boolean
    - `externalChatId` string, nullable
    - `status` string
    - `policy` string

## Response `200`

Successful response

- object
  - `ok` boolean, required
  - `contact` object, required
    - `id` string, required
    - `displayName` string, required
    - `role` string, required
    - `notes` string, nullable, required
    - `contactType` string, nullable, required
    - `principalId` string, nullable, required
    - `userFile` string, nullable, required
    - `createdAt` number, required
    - `updatedAt` number, required
    - `interactionCount` number, required
    - `lastInteraction` number, nullable, required
    - `assistantMetadata` object, nullable, required
      - `species` string, required
      - `metadata` object, nullable, required
    - `channels` object[], required
      - `id` string, required
      - `contactId` string, required
      - `type` string, required
      - `address` string, required
      - `isPrimary` boolean, required
      - `externalChatId` string, nullable, required
      - `externalUserId` string, required — Compat alias for address (older macOS clients)
      - `status` string, nullable, required
      - `policy` string, nullable, required
      - `verifiedAt` number, nullable, required
      - `verifiedVia` string, nullable, required
      - `inviteId` string, nullable, required
      - `revokedReason` string, nullable, required
      - `blockedReason` string, nullable, required
      - `lastSeenAt` number, nullable, required
      - `interactionCount` number, required
      - `lastInteraction` number, nullable, required
      - `createdAt` number, nullable, required
      - `updatedAt` number, nullable, required

---

[API](https://skmtc.net/vellum-ai/apis/vellum-gateway-api.md) · [All operations](https://skmtc.net/vellum-ai/apis/vellum-gateway-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/vellum-ai/vellum-gateway-api/versions/0ce2a9dec32d/schema)
