---
title: "Crea un contacto. Refleja DELETE /contacts/:id: también crea el suscriptor en Meteor CRM (uChat)."
method: POST
path: "/contacts"
tags: ["Contacts"]
---

# Crea un contacto. Refleja DELETE /contacts/:id: también crea el suscriptor en Meteor CRM (uChat).

`POST /contacts`

## Request

- Base URL: `https://api.met.meteor.com.co/api/v1`
- URL: `https://api.met.meteor.com.co/api/v1/contacts`
- Auth: one of:
  - `bearer` (a scheme the document does not define)
  - HTTP bearer

Crea el contacto **y también el suscriptor en el CRM**, no solo la fila: por eso es la contraparte exacta de `DELETE /contacts/{contactId}`. Para cargar muchos no lo llames en un bucle — `POST /contacts/import` hace el lote y sabe qué hacer con los repetidos.

**Si el contacto ya existe.** La deduplicación es por la identidad del canal (`data.$user_ns` + canal; en WhatsApp directo son los dígitos del teléfono), no por el teléfono a secas. Si ya hay un contacto con esa identidad y su teléfono coincide con el pedido (normalizado: `3001234567`, `+57 300 123 4567` y `573001234567` son el mismo), se devuelve ese contacto con `created: false` y `matched_by: "user_ns"`, **sin aplicarle nada del cuerpo** — para cambiar sus datos usa `PATCH /contacts/{contactId}`. Si guarda **otro** teléfono, responde `409 contact_identity_conflict` y no devuelve a nadie: nunca recibes a otra persona como si fuera la que pediste. Mira siempre `created` antes de etiquetar o actualizar: el código HTTP es 201 en los dos casos.

**Nombre.** Si mandas `name` sin `first_name`, `data.$first_name` queda con la primera palabra y, si tampoco mandas `last_name`, `data.$last_name` con el resto.

## Request body

- CreateContactDto
  - `channel_id` number
  - `email` string, email
  - `first_name` string
  - `gender` string
  - `image` string
  - `last_name` string
  - `name` string
  - `phone` string

## Response `201`

El contacto. `created: true` si se creó; `created: false` (con `matched_by`) si ya existía con esta identidad en el canal y es la misma persona. Ambos casos responden 201.

- object: Sobre en el que viaja toda respuesta correcta de la API. El recurso está en `data`. Los SDKs oficiales lo desenvuelven por ti; un cliente hecho a mano tiene que leer `.data`.
  - `success` true, required: Siempre `true` en una respuesta 2xx.
  - `data` CreateContactResponseDto, required
    - `app_url` string, nullable, required: Enlace que abre la conversación de este contacto en Met. Guárdalo en tu CRM para ir directo al chat: no cambia aunque el workspace cambie de nombre (no lleva el slug). Abrirlo pide sesión en Met y permiso sobre el contacto; no es un enlace público.
    - `channel_id` number, nullable, required: Canal por el que se conversa con este contacto (resuelto desde `data.$channel_id`).
    - `channel_name` string, nullable, required
    - `channel_type` string, nullable, required
    - `code` string, nullable: Código corto del registro. No es la identidad del contacto en el canal.
    - `collection_id` number, required: Colección `_contacts` del workspace a la que pertenece.
    - `conversation_line_id` string: Línea cuyo estado de atención fue proyectado en data.
    - `created` boolean, required: `true` si se creó un contacto nuevo; `false` si ya existía con esta identidad.
    - `created_at` string, nullable
    - `data` object, required: Los campos del contacto. Sistema con `$` (`$name`, `$phone`, `$email`, `$status`, `$tags`, `$channel_id`, `$user_ns`, `$assigned_user_id`, `$autopilot_enabled`, `$last_message_at`); personalizados con su `field_key` pelado. Descubre los personalizados del workspace con `GET /variables/contact-fields`.
    - `id` number, required
    - `line_attention_enabled` boolean: El workspace mantiene la atención (estado, asesor y piloto) por línea de WhatsApp.
    - `matched_by` 'user_ns': Solo cuando `created` es `false`: por qué campo se reconoció al contacto existente. Hoy siempre `user_ns` (la identidad del canal; en WhatsApp directo son los dígitos del teléfono).
    - `updated_at` string, nullable

## Other responses

- `400`: La request no es válida: un campo no pasa validación, falta un parámetro requerido o el recurso no admite la transición solicitada.
- `401`: API key ausente, inválida, revocada o expirada — o el workspace está bloqueado.
- `403`: La key está autenticada pero no puede ejecutar esta operación: scope faltante, capacidad deshabilitada, modo test restringido o recurso fuera de su cartera.
- `404`: El recurso no existe o no está disponible dentro del alcance de la key. No revela la existencia de recursos de otros tenants.
- `409`: `contact_identity_conflict`: la identidad del canal ya pertenece a un contacto con otro teléfono (u otro email, en un alta solo por email). No se crea ni se devuelve; el mensaje trae el id del existente. `contact_identity_ambiguous`: hay más de un contacto con esa identidad; fusiónalos antes de reintentar.
- `429`: Se superó el límite por minuto de la key o la cuota del plan. Respeta `Retry-After`; el SDK ya reintenta solo.
- `500`: Error del servidor o del Met que ejecutaba. El SDK reintenta los 5xx con backoff.

---

[API](https://skmtc.dev/meteor/apis/met-public-api.md) · [All operations](https://skmtc.dev/meteor/apis/met-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/meteor/apis/met-public-api/revisions/fc6d3aad75de?raw)
