*MCP › Referencia › CRM › Contactos*

# Relacionar dos contactos

> Vincula un contacto con otro mediante un rol (la persona de contacto de una empresa, el director de una producción).

Una empresa que relaciona a una persona debe indicar el rol (400 en caso contrario); una persona que relaciona a una empresa no debe indicarlo (el rol vive en la relación inversa); cualquier otro par es libre y el rol se registra. 409 si el par ya estaba relacionado. Devuelve la relación tal como queda registrada. Devuelve el contacto completo, con `relatedContacts` tal como quedan ahora, la misma proyección que su GET.

HERRAMIENTA `filmo_contacts_related_add` · `contacts:write` · 120/min

## Argumentos

| Nombre | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `contactId` | string | Sí | Identificador del contacto principal. |
| `relationRole` | string | No | Rol de la relación, p. ej. "Director", "Persona de contacto". Obligatorio cuando una empresa relaciona a una persona; no permitido cuando una persona relaciona una empresa. |
| `relatedContactId` | string | Sí | Contacto con el que relacionar. |
| `idempotencyKey` | string | No | Clave de idempotencia elegida por el cliente (se recomienda un UUID). Repetir la misma clave con los mismos argumentos en 24 h devuelve la respuesta almacenada sin volver a ejecutar; con argumentos distintos responde 422. Es la forma segura de reintentar tras un fallo de red. |
| `ifMatch` | string | No | Bloqueo optimista: el meta.etag que obtuviste de la lectura de detalle de este recurso (o "*"). Si el recurso ha cambiado desde entonces, la llamada falla con 412 precondition_failed antes de escribir nada; léelo de nuevo y reintenta. Omítelo para escribir sin condiciones. |

## Resultado

En un éxito el resultado lleva `structuredContent` con `data` y `meta`. Estos son los atributos de `data`.

| Nombre | Tipo | Descripción |
| --- | --- | --- |
| `id` | string | Identificador único del contacto. |
| `name` | string | Nombre del contacto (persona o empresa). |
| `contactType` | string | Tipo de contacto: person (particular) o company (negocio). `person`, `company` |
| `role` | string | Rol del contacto: client, provider, lead, debtor, creditor, student, teacher o unspecified. `client`, `provider`, `lead`, `debtor`, `creditor`, `student`, `teacher`, `unspecified` |
| `status` | string | Estado del contacto: active (operativo), inactive (desactivado) o archived (cerrado, conservado como histórico). `active`, `inactive`, `archived` |
| `nif` | string | NIF/CIF o número de identificación fiscal; null si no se ha registrado. |
| `commercialName` | string | Nombre comercial; null si coincide con el nombre o no consta. |
| `position` | string | Cargo o puesto de la persona de contacto; null si no está registrado. |
| `contactNumber` | string | Número de contacto asignado por la cuenta (referencia interna); null si no consta. |
| `emails` | object[] | Lista de direcciones de correo electrónico del contacto. |
| `emails.id` | string | Identificador interno del correo electrónico dentro del contacto. |
| `emails.label` | string | Etiqueta descriptiva del email; null si no tiene. |
| `emails.email` | string | Dirección de email. |
| `emails.isPrimary` | boolean | Si este es el email principal del contacto. |
| `billingEmail` | string | Email de facturación dedicado; null significa que se usa el email principal. |
| `phoneNumbers` | object[] | Lista de teléfonos del contacto. |
| `phoneNumbers.id` | string | Identificador interno del teléfono dentro del contacto. |
| `phoneNumbers.label` | string | Etiqueta descriptiva del teléfono; null si no tiene. |
| `phoneNumbers.number` | string | Número de teléfono. |
| `phoneNumbers.countryCode` | string | Prefijo telefónico internacional del país (p. ej. "+34"); null si no consta. |
| `phoneNumbers.isPrimary` | boolean | Si este es el teléfono principal del contacto. |
| `websites` | object[] | Lista de sitios web del contacto. |
| `websites.id` | string | Identificador interno del sitio web dentro del contacto. |
| `websites.label` | string | Etiqueta descriptiva del sitio web; null si no tiene. |
| `websites.url` | string | URL del sitio web. |
| `addresses` | object[] | Lista de direcciones del contacto. |
| `addresses.id` | string | Identificador interno de la dirección dentro del contacto. |
| `addresses.label` | string | Etiqueta descriptiva de la dirección; null si no tiene. |
| `addresses.addressLine1` | string | Primera línea de la dirección; null si no consta. |
| `addresses.addressLine2` | string | Segunda línea de la dirección; null si no consta. |
| `addresses.city` | string | Ciudad; null si no consta. |
| `addresses.province` | string | Provincia o región; null si no se ha registrado. |
| `addresses.postcode` | string | Código postal; null si no se ha registrado. |
| `addresses.country` | string | País; null si no consta. |
| `addresses.isMain` | boolean | Si esta es la dirección principal del contacto. |
| `folder` | string | Carpeta o agrupación organizativa; null si el contacto no está clasificado. |
| `discountPercentage` | number | Porcentaje de descuento general del contacto (0-100); null si no hay descuento configurado. |
| `preferredLanguage` | string | Idioma preferido del contacto; null si no se ha registrado. |
| `currency` | string | Moneda por defecto del contacto como código ISO 4217; null si no consta. |
| `paymentMethod` | object | Método de pago preferido del contacto; null si no está configurado. |
| `paymentMethod.type` | string | Tipo de método de pago: bank_transfer, card, cash, sepa_direct_debit u other. `bank_transfer`, `card`, `cash`, `other`, `sepa_direct_debit` |
| `paymentMethod.customValue` | string | Detalle en texto libre cuando el tipo es "other" (por ejemplo, un método registrado antes de configurarse); null en caso contrario. |
| `paymentDays` | integer[] | Días del mes en que el contacto hace pagos; null si no está configurado. |
| `expirationDays` | integer | Días de vencimiento por defecto de las facturas del contacto; null si no está configurado. |
| `subscribedToMarketing` | boolean | Si el contacto está suscrito a comunicaciones de marketing. |
| `isAppUser` | boolean | Si el contacto tiene acceso a la app. |
| `customFields` | object<string, any> | Valores de los campos personalizados por identificador de campo personalizado; las definiciones están en `/api/v1/custom-fields`. |
| `createdAt` | string<date-time> | Fecha de creación en ISO 8601 con desplazamiento. |
| `updatedAt` | string<date-time> | Fecha de la última actualización en ISO 8601 con desplazamiento. |
| `relatedContacts` | object[] | Contactos relacionados con este contacto (p. ej. las personas de una empresa). |
| `relatedContacts.id` | string | Identificador único del contacto relacionado. |
| `relatedContacts.name` | string | Nombre del contacto relacionado. |
| `relatedContacts.commercialName` | string | Nombre comercial del contacto relacionado; null si no consta. |
| `relatedContacts.contactType` | string | Tipo del contacto relacionado: person o company. `person`, `company` |
| `relatedContacts.role` | string | Rol del contacto relacionado. `client`, `provider`, `lead`, `debtor`, `creditor`, `student`, `teacher`, `unspecified` |
| `relatedContacts.status` | string | Estado del contacto relacionado: active, inactive o archived. `active`, `inactive`, `archived` |
| `relatedContacts.relationRole` | string | Rol de la relación entre los dos contactos (p. ej. "empleado de"); null si no consta. |

*Llamada · filmo_contacts_related_add*

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "filmo_contacts_related_add",
    "arguments": {
      "contactId": "cont_8f2a1c",
      "relatedContactId": "rela_8f2a1c"
    }
  }
}
```

*Resultado (generado desde el esquema)*

```json
{
  "structuredContent": {
    "data": {
      "id": "id_8f2a1c",
      "name": "Example",
      "contactType": "person",
      "role": "client",
      "status": "active",
      "nif": "00000000T",
      "commercialName": "Example",
      "position": "<position>",
      "contactNumber": "<contactNumber>",
      "emails": [
        {
          "id": "id_8f2a1c",
          "label": "Example",
          "email": "ana@example.com",
          "isPrimary": true
        }
      ],
      "billingEmail": "ana@example.com",
      "phoneNumbers": [
        {
          "id": "id_8f2a1c",
          "label": "Example",
          "number": "<number>",
          "countryCode": "ES",
          "isPrimary": true
        }
      ],
      "websites": [
        {
          "id": "id_8f2a1c",
          "label": "Example",
          "url": "https://example.com"
        }
      ],
      "addresses": [
        {
          "id": "id_8f2a1c",
          "label": "Example",
          "addressLine1": "<addressLine1>",
          "addressLine2": "<addressLine2>",
          "city": "<city>",
          "province": "<province>",
          "postcode": "<postcode>",
          "country": "ES",
          "isMain": true
        }
      ],
      "folder": "<folder>",
      "discountPercentage": 1,
      "preferredLanguage": "es-ES",
      "currency": "EUR",
      "paymentMethod": {
        "type": "bank_transfer",
        "customValue": "<customValue>"
      },
      "paymentDays": [
        1
      ],
      "expirationDays": 1,
      "subscribedToMarketing": true,
      "isAppUser": true,
      "customFields": {
        "key": "<key>"
      },
      "createdAt": "2026-09-01T08:00:00Z",
      "updatedAt": "2026-09-01T08:00:00Z",
      "relatedContacts": [
        {
          "id": "id_8f2a1c",
          "name": "Example",
          "commercialName": "Example",
          "contactType": "person",
          "role": "client",
          "status": "active",
          "relationRole": "<relationRole>"
        }
      ]
    },
    "meta": {
      "idempotencyKey": "<the key you sent, or the one the server generated>",
      "rateLimit": {
        "limit": 120,
        "remaining": 119,
        "reset": 42
      }
    }
  }
}
```

## La misma operación por REST

Esta herramienta ejecuta [`POST /api/v1/contacts/{contactId}/related-contacts`](https://docs.filmo.io/es/rest-api/endpoint-reference/contacts/relate-two-contacts).

---

URL canónica: https://docs.filmo.io/es/mcp/tools/contacts/filmo-contacts-related-add  
Última actualización: 2026-10-25