---
title: "Create a contact"
method: POST
path: "/contacts"
tags: ["Contacts"]
---

# Create a contact

`POST /contacts`

Create a new contact. At least one of `email` or `phone_number` is required.

If a contact with the same email or phone number already exists, a `409 Conflict`
error is returned with the `id` of the existing contact in `error.id`. Use the **Update a contact** endpoint to modify existing contacts.

If a previously deleted contact matches the provided email or phone number,
the contact is restored with the new data.

When `sms_consent` is `subscribed`, Privy automatically sends a TCPA-required
welcome SMS to the contact. Pass `send_welcome_sms: false` to suppress this
message if you have already collected consent outside of Privy.

**Required scope:** `contacts_write`

## Request body

- CreateContactRequest — At least one of `email` or `phone_number` is required. Use `email_consent` and `sms_consent` to set the contact's marketing consent status at creation time.
  - `email` string, email — Contact's email address.
  - `phone_number` string — Contact's phone number in E.164 format.
  - `first_name` string — Contact's first name.
  - `last_name` string — Contact's last name.
  - `tags` string[] — Tags to apply to the contact.
  - `custom_fields` object — Flat key-value pairs. Nested objects are not allowed.
  - `email_consent` 'subscribed' | 'unsubscribed' | 'never_subscribed' | 'suppressed' — Email marketing consent status. If not provided, defaults to `never_subscribed`. `compliance_suppressed` is read-only and cannot be set on create.
  - `sms_consent` 'subscribed' | 'unsubscribed' | 'never_subscribed' | 'single_opt_in' — SMS marketing consent status. `pending` is read-only and cannot be set. `subscribed` and `single_opt_in` require a valid `phone_number` from a supported country. Cannot be `unsubscribed` for new contacts (no existing consent to revoke).
  - `send_welcome_sms` boolean — When `sms_consent` is set to `subscribed` and the contact transitions to a confirmed SMS opt-in state, Privy sends a TCPA-required welcome SMS. Set to `false` to suppress this message when you have already collected consent outside of Privy.

## Response `201`

Contact created successfully.

- object
  - `data` Contact
    - `id` string — Stable, unique identifier for the contact. Use this value in `/v1/contacts/{id}` endpoints.
    - `first_name` string
    - `last_name` string
    - `email` string, email
    - `email_consent` 'subscribed' | 'unsubscribed' | 'never_subscribed' | 'suppressed' | 'compliance_suppressed' — Email marketing consent status. - `subscribed` — contact opted into email (explicit or implicit consent). - `unsubscribed` — contact opted out of email. - `never_subscribed` — no opt-in and no opt-out. - `suppressed` — merchant-suppressed (bounce list, manual action). - `compliance_suppressed` — system-suppressed (CAN-SPAM, abuse complaint). Read-only.
    - `phone_number` string
    - `sms_consent` 'subscribed' | 'unsubscribed' | 'never_subscribed' | 'single_opt_in' | 'pending' — SMS marketing consent status. - `subscribed` — contact has confirmed SMS opt-in. - `unsubscribed` — contact opted out of SMS. - `never_subscribed` — no opt-in and no opt-out. - `single_opt_in` — merchant collected a single opt-in (not yet confirmed). - `pending` — Privy is awaiting a confirmation reply. Read-only.
    - `tags` string[]
    - `custom_fields` object
    - `created_at` string, date-time
    - `updated_at` string, date-time

## Other responses

- `401` — Missing or invalid bearer token.
- `403` — Token lacks the required scope for this endpoint.
- `409` — A contact with this email or phone number already exists. The response includes the `id` of the existing contact in `error.id`.
- `422` — One or more fields failed validation.
- `429` — Rate limit exceeded. Retry after the specified time.

---

[API](https://skmtc.dev/privy/apis/privy-api.md) · [All operations](https://skmtc.dev/privy/apis/privy-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/privy/privy-api/revisions/5378aff56b9a/schema)
