*Visión general › Conceptos básicos*

# Registros e ids

> Cada registro tiene un id opaco que asigna Filmo. Guarda tus propios ids en una tabla de correspondencias de tu lado, y usa un campo de referencia solo donde la API lo tenga.

## Los ids son opacos

Los identificadores son cadenas opacas. No supongas nunca su formato, su longitud ni su orden, y no construyas ninguno. Los cursores de paginación son opacos de la misma manera. Los números legibles, como `orderNumber` o `contactNumber`, son para las personas: usa `id` para direccionar un registro.

## Dónde puede estar tu id

Solo algunos recursos tienen un campo escribible para una referencia de tu sistema. La tabla se genera a partir de la especificación.

| Campo | Sí o no |
| --- | --- |
| `ContactDto.contactNumber` | No |
| `ContactDetailDto.contactNumber` | No |
| `ContactCreateBody.contactNumber` | Sí |
| `ContactUpdateBody.contactNumber` | Sí |
| `OrderDto.externalReference` | No |
| `OrderDetailDto.externalReference` | No |
| `ProjectDto.externalReference` | No |
| `ProjectDetailDto.externalReference` | No |
| `ProjectCreateBody.externalReference` | Sí |
| `StaffMemberDto.externalRef` | No |
| `StaffUpdateBody.externalRef` | Sí |
| `ProjectUpdateBody.externalReference` | Sí |
| `upsertExternalInvoice.originSystem` | Sí |
| `upsertExternalInvoice.originExternalId` | Sí |

| Recurso | Qué existe hoy |
| --- | --- |
| Proyectos | `externalReference` al crear y `externalReference` al actualizar, hasta 200 caracteres. |
| Personal | `externalRef`, solo al actualizar; el cuerpo de creación no lo tiene. `null` lo borra. |
| Facturas emitidas en otro sitio | El par `originSystem` y `originExternalId` en la ruta de `PUT /api/v1/invoices/external/{originSystem}/{originExternalId}` es la clave del espejo: repetirlo actualiza el mismo espejo. |
| Pedidos | `externalReference` se devuelve, pero los cuerpos de creación y actualización no tienen ese campo: puedes leerlo, pero todavía no escribirlo a través de la API. |
| Contactos | No hay campo de referencia externa. `contactNumber` es una referencia libre, de hasta 50 caracteres, que puedes escribir al crear y al actualizar. No es único: Filmo no impide que dos contactos compartan un número, así que comprueba lo que devuelve una búsqueda. |

## Buscar contactos

[`POST /api/v1/contacts/lookup`](https://docs.filmo.io/es/rest-api/endpoint-reference/contacts/look-up-contacts-by-external-reference) acepta hasta 200 referencias y compara cada una, de forma exacta y sin ninguna normalización, con el `contactNumber` de los contactos, y con nada más. Devuelve dos listas: `notFound`, las referencias que no coinciden con ningún contacto, y `contacts`, los contactos que coincidieron, cada uno con `id`, `name` y `contactNumber`. No escribe nada, aunque sea un POST.

La respuesta no empareja una referencia con un contacto, y el orden de `contacts` no está garantizado. Empárejalos tú mismo comparando el `contactNumber` de cada contacto con tu referencia. Como `contactNumber` no es único, pueden devolverse varios contactos para una referencia: decide qué hacer en ese caso en lugar de tomar el primero. Usa `notFound` para saber qué crear, y guarda el `id` de Filmo en tu propia tabla cuando lo tengas.

## Mantén tu propia tabla de correspondencias

Guarda tu id externo y el `id` de Filmo juntos en tu propia base de datos. Una `Idempotency-Key` solo deduplica reintentos durante 24 horas; no sustituye esa tabla ([Idempotencia](https://docs.filmo.io/es/rest-api/guides/idempotency)). Con la tabla puedes actualizar el registro correcto, detectar duplicados y decidir qué eliminar. Para el patrón en un CRM, consulta el [tutorial de sincronización de contactos](https://docs.filmo.io/es/rest-api/tutorials/crm-contact-sync).

## Campos personalizados

Los valores de los campos personalizados se leen en el mapa `customFields` de un registro, indexados por el identificador de la definición del campo. Las definiciones vienen de [`GET /api/v1/custom-fields`](https://docs.filmo.io/es/rest-api/endpoint-reference/custom-fields/list-custom-field-definitions), con la entidad a la que se aplica cada una (`applyAt`), el tipo y los valores que acepta un desplegable. Los valores viajan dentro de cada recurso; el endpoint de definiciones no los devuelve. v1 no tiene ninguna operación que escriba un campo personalizado: los cuerpos de creación y actualización no tienen la propiedad `customFields`, así que establécelos en la app.

## Etiquetas y notas

- Etiquetas: [`GET /api/v1/tags`](https://docs.filmo.io/es/rest-api/endpoint-reference/tags/list-tags) devuelve el vocabulario con cuántas entidades usan cada una. [`POST /api/v1/tags/{tagId}/assignments`](https://docs.filmo.io/es/rest-api/endpoint-reference/tags/assign-a-tag-to-an-entity) asocia una etiqueta existente a una entidad. [`DELETE /api/v1/tags/{tagId}/assignments`](https://docs.filmo.io/es/rest-api/endpoint-reference/tags/remove-a-tag-from-an-entity) quita el vínculo y no borra la etiqueta.
- Notas: [`POST /api/v1/notes`](https://docs.filmo.io/es/rest-api/endpoint-reference/notes/write-a-note-on-an-entity) escribe una nota en una entidad y [`GET /api/v1/notes`](https://docs.filmo.io/es/rest-api/endpoint-reference/notes/list-the-notes-of-an-entity) lee las notas de una entidad, nunca las de todas. No se devuelve quién escribió una nota. Mencionar a usuarios les envía una notificación en Filmo.

---

URL canónica: https://docs.filmo.io/es/concepts/records-and-ids  
Última actualización: 2026-10-09