Un contacto representa una persona física o empresa con la que mantienes una relación contable: clientes a los que facturas, proveedores de los que recibes gastos y empleados a los que pagas nóminas.

En FacturaDirecta un mismo contacto puede actuar simultáneamente como cliente, proveedor y empleado. No son tipos excluyentes: son facetas que se activan al asociar al contacto la cuenta contable correspondiente.

Facetas: cliente, proveedor, empleado

Las facetas se controlan a través del objeto content.main.accounts:

  • accounts.client → habilita al contacto como cliente (cuenta 430* por defecto).
  • accounts.provider → habilita al contacto como proveedor (cuenta 400/410*).
  • accounts.employee → habilita al contacto como empleado (cuenta 465*).

Cada faceta principal tiene su contraparte de anticipos (clientCredit, providerCredit, employeeCredit). Si indicas solo la cuenta principal con el prefijo esperado, FacturaDirecta autocompleta la de anticipos con el valor por defecto de la empresa.

Comportamiento por defecto al crear un contacto. Si no envías accounts, el contacto se crea como cliente con las cuentas contables por defecto. Para crear un proveedor o un empleado debes indicarlo explícitamente.

Para listar contactos por faceta, usa los filtros isClient, isProvider o isEmployee en GET /contacts. Devuelven los contactos que tienen la cuenta correspondiente asignada.

Cuando el contacto actúa como cliente, content.main.owner identifica al usuario responsable de esa cartera. Se usa con roles personalizados para limitar la visibilidad a clientes asignados. Si creas el contacto con OAuth y no envías owner, la API asigna como responsable al usuario autenticado; con apiKey se deja vacío salvo que lo envíes en el body.

Permisos por faceta

Con una aplicación conectada o un rol personalizado, los permisos de clientes, proveedores y empleados se evalúan por separado:

  • Los listados y las consultas solo devuelven contactos con al menos una faceta que la credencial pueda leer.
  • Crear, actualizar, etiquetar o borrar exige permiso de escritura sobre todas las facetas del contacto.
  • Al actualizar también se comprueban las facetas anteriores. Quitar una cuenta de proveedor, por ejemplo, sigue requiriendo permiso para modificar proveedores.

Si falta un permiso, la respuesta es 403. Una aplicación conectada recibe code: "connection_permission_insufficient" y manageUrl cuando el usuario puede ampliar la conexión. Si la limitación procede del rol, el código es user_role_insufficient. Consulta Errores y validaciones.

Campos personalizados

content.main.customFields es un mapa de valores indexado por el ID estable cfi_<uuid v4> de cada campo personalizado. Las claves deben corresponder a definiciones existentes. También se aceptan definiciones borradas para conservar contactos históricos; un ID desconocido o con formato incorrecto produce 400 Bad Request.

Enlace a la aplicación

Las respuestas que devuelven un contacto incluyen webUrl junto al resto de los datos. En los listados, cada elemento de items lleva su propio enlace.

webUrl abre la ficha del elemento en la aplicación web de FacturaDirecta. Puedes mostrarlo como enlace en tu integración sin construir rutas internas. El navegador pedirá iniciar sesión con un usuario que tenga acceso a la empresa. Es un campo opcional y no es un endpoint de la API: trátalo como una URL para el usuario, no como una URL a la que enviar $ACCESS_TOKEN.

Operaciones

Lista de contactos

GET /{companyId}/contacts devuelve los contactos de la empresa indicada, paginados.

Parámetros de consulta:

  • search — búsqueda libre por nombre, apellidos o nombre comercial.
  • fiscalId — identificador fiscal exacto (sin separadores).
  • vatEU — identificador IVA intracomunitario.
  • externalId — referencia externa asignada al importar.
  • phone — teléfono exacto.
  • country — código país ISO 3166-1 Alpha-2 (ES, FR…).
  • isClient, isProvider, isEmployee — facetas (ver sección superior).
  • allTheseTags, anyOfTheseTags — filtros por etiquetas concretas.
  • hasTags — true devuelve solo contactos con al menos una etiqueta y false, solo contactos sin etiquetas.
  • sortBy — campo de orden.
  • related — recursos relacionados a expandir.

Ver Paginación para los parámetros comunes (offset, limit, hasMore).

Ejemplo de respuesta JSON
json
{
  "pagination": { "offset": 0, "limit": 50, "total": 124 },
  "items": [
    {
      "content": {
        "type": "contact",
        "uuid": "con_2c4f8e21-7b3a-4d9c-9e1f-a8b7c6d5e4f3",
        "main": {
          "title": "Acme Diseño",
          "name": "Acme Diseño S.L.",
          "email": "facturacion@acme.es",
          "phone": "+34 932 000 000",
          "address": "Carrer Aribau 123",
          "zipcode": "08036",
          "city": "Barcelona",
          "region": "Barcelona",
          "country": "ES",
          "fiscalId": "B12345674",
          "fiscalIdCountry": "ES",
          "accounts": {
            "client": "4300001",
            "clientCredit": "4380001"
          },
          "currency": "EUR"
        }
      },
      "tags": ["agencia", "barcelona"],
      "creationDate": "2025-11-14T10:22:31.000Z",
      "modificationDate": "2026-04-02T08:15:00.000Z"
    }
  ]
}
Copy as cURL
shell
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://app.facturadirecta.com/api/$COMPANY_ID/contacts?isClient=true&country=ES&limit=50"

Crear contacto

POST /{companyId}/contacts crea un contacto en la empresa indicada.

Parámetros del body:

  • content.type — siempre "contact".
  • content.main — campos del contacto.
  • tags (opcional) — lista de etiquetas a asociar.

Notas:

  • Si omites accounts, el contacto se crea como cliente con las cuentas por defecto de la empresa.
  • fiscalId se valida cuando fiscalIdCountry es ES (o country es ES si no se indica fiscalIdCountry).
  • language (opcional) es el idioma en que se imprimen y se envían los documentos del contacto, como código ISO 639-1 (es, ca, en…). Las facturas, presupuestos y demás documentos nuevos lo toman al asignarles el contacto. Sin valor, cada documento sale en el idioma base de su plantilla.
  • La respuesta es el contacto creado completo, en el mismo formato que Obtener un contacto.

Límites del plan. Los planes limitan cuántos clientes y cuántos empleados puede tener la empresa a la vez:

PlanClientesEmpleados
Gratis101
Bronce1002
PlataSin límite5
OroSin límite20
DiamanteSin límiteSin límite

Los límites solo bloquean crear: los contactos que ya existen siguen funcionando aunque la empresa baje de plan, y borrar uno libera hueco. Al superarlos, la respuesta es 403 con el código plan_limit_exceeded (ver Errores). Cuentan solo los contactos con la faceta correspondiente: un proveedor no consume cupo de cliente ni de empleado.

Ejemplo de request JSON
json
{
  "content": {
    "type": "contact",
    "main": {
      "name": "Acme Diseño S.L.",
      "email": "facturacion@acme.es",
      "fiscalId": "B12345674",
      "address": "Carrer Aribau 123",
      "zipcode": "08036",
      "city": "Barcelona",
      "country": "ES"
    }
  },
  "tags": ["agencia", "barcelona"]
}
Copy as cURL
shell
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{
    "content": {
      "type": "contact",
      "main": {
        "name": "Acme Diseño S.L.",
        "email": "facturacion@acme.es",
        "fiscalId": "B12345674",
        "address": "Carrer Aribau 123",
        "zipcode": "08036",
        "city": "Barcelona",
        "country": "ES"
      }
    },
    "tags": ["agencia", "barcelona"]
  }' \
  "https://app.facturadirecta.com/api/$COMPANY_ID/contacts"

Obtener un contacto

GET /{companyId}/contacts/{id} devuelve un contacto por su ID.

Parámetros:

  • related (opcional) — recursos relacionados a expandir, por ejemplo invoices,bills.
Ejemplo de respuesta JSON
json
{
  "content": {
    "type": "contact",
    "uuid": "con_2c4f8e21-7b3a-4d9c-9e1f-a8b7c6d5e4f3",
    "main": {
      "title": "Acme Diseño",
      "name": "Acme Diseño S.L.",
      "email": "facturacion@acme.es",
      "phone": "+34 932 000 000",
      "address": "Carrer Aribau 123",
      "zipcode": "08036",
      "city": "Barcelona",
      "region": "Barcelona",
      "country": "ES",
      "fiscalId": "B12345674",
      "fiscalIdCountry": "ES",
      "accounts": {
        "client": "4300001",
        "clientCredit": "4380001"
      },
      "currency": "EUR"
    }
  },
  "tags": ["agencia", "barcelona"],
  "creationDate": "2025-11-14T10:22:31.000Z",
  "modificationDate": "2026-04-02T08:15:00.000Z",
  "related": {}
}
Copy as cURL
shell
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://app.facturadirecta.com/api/$COMPANY_ID/contacts/con_2c4f8e21-7b3a-4d9c-9e1f-a8b7c6d5e4f3"

Actualizar contacto

PUT /{companyId}/contacts/{id} sustituye el contenido completo del contacto. No es un PATCH: lo que no envíes, se borra.

Parámetros del body: mismo formato que Crear contacto. Para añadir una faceta a un contacto existente (por ejemplo, convertir un cliente en cliente-y-proveedor) reenvía el contacto completo con las cuentas adicionales en accounts.

Respuesta: el contacto actualizado completo, en el mismo formato que Obtener un contacto.

Ejemplo de request JSON
json
{
  "content": {
    "type": "contact",
    "main": {
      "name": "Acme Diseño S.L.",
      "email": "facturacion@acme.es",
      "phone": "+34 932 000 000",
      "fiscalId": "B12345674",
      "address": "Carrer Aribau 123",
      "zipcode": "08036",
      "city": "Barcelona",
      "country": "ES",
      "accounts": {
        "client": "4300001",
        "clientCredit": "4380001",
        "provider": "4100001",
        "providerCredit": "4070001"
      }
    }
  }
}
Copy as cURL
shell
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" -X PUT \
  -d '{
    "content": {
      "type": "contact",
      "main": {
        "name": "Acme Diseño S.L.",
        "email": "facturacion@acme.es",
        "phone": "+34 932 000 000",
        "fiscalId": "B12345674",
        "address": "Carrer Aribau 123",
        "zipcode": "08036",
        "city": "Barcelona",
        "country": "ES",
        "accounts": {
          "client": "4300001",
          "clientCredit": "4380001",
          "provider": "4100001",
          "providerCredit": "4070001"
        }
      }
    }
  }' \
  "https://app.facturadirecta.com/api/$COMPANY_ID/contacts/con_2c4f8e21-7b3a-4d9c-9e1f-a8b7c6d5e4f3"

Borrar contacto

DELETE /{companyId}/contacts/{id} elimina un contacto de la empresa.

Restricciones. Si el contacto tiene documentos asociados (facturas, gastos, nóminas), la API rechaza el borrado con 409 Conflict y un mensaje indicando el motivo. En ese caso, reasigna sus documentos a otro contacto antes de borrarlo.

Respuesta: { "result": true }.

Copy as cURL
shell
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" -X DELETE \
  "https://app.facturadirecta.com/api/$COMPANY_ID/contacts/con_2c4f8e21-7b3a-4d9c-9e1f-a8b7c6d5e4f3"

Actualizar etiquetas de contacto

PUT /{companyId}/contacts/{id}/tags reemplaza el conjunto de etiquetas de un contacto sin tocar el resto del contenido. Útil cuando solo quieres reclasificar sin reenviar la estructura completa del contacto.

Parámetros del body:

  • tags — lista completa de etiquetas (sustituye, no añade).
Ejemplo de request JSON
json
{
  "tags": ["agencia", "premium", "barcelona"]
}
Copy as cURL
shell
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" -X PUT \
  -d '{"tags":["agencia","premium","barcelona"]}' \
  "https://app.facturadirecta.com/api/$COMPANY_ID/contacts/con_2c4f8e21-7b3a-4d9c-9e1f-a8b7c6d5e4f3/tags"

Identificador fiscal

fiscalId es obligatorio para emitir facturas a clientes españoles. Se valida formato (NIF, CIF o NIE) y se almacena sin separadores ni espacios. Si no indicas fiscalIdCountry, se asume el mismo país que la dirección fiscal del contacto.

Para contactos extracomunitarios sin identificador fiscal, deja el campo vacío e informa el nombre y el domicilio completos. Si TicketBAI no está activo, sus facturas se emiten por defecto como facturas completas sin identificación del destinatario (art. 6.1.d del RD 1619/2012), no como simplificadas. Con VeriFactu se registran como F2. Para contactos intracomunitarios, usa el campo vatEU (formato con prefijo de país: ESB12345674).

Versiones

GET /{companyId}/contacts/{id}/versions lista las versiones de el contacto: su alta, cada modificación, su eliminación y su recuperación, con quién y cuándo, aunque se haya eliminado. GET /{companyId}/contacts/{id}/versions/{versionId} devuelve la copia de una versión, en el mismo formato que GET /{companyId}/contacts/{id}, y los cambios respecto a la versión anterior. Sirven para ver qué se cambió y recuperar datos: ver Versiones de documentos.

Errores comunes

  • 400 ValidationError — fiscalId con formato inválido para el país indicado.
  • 403 con código plan_limit_exceeded — se ha alcanzado el máximo de clientes o de empleados del plan.
  • 403 con código connection_permission_insufficient o user_role_insufficient — falta permiso sobre alguna faceta del contacto.
  • 409 Conflict — borrado de contacto con documentos asociados.
  • 409 Conflict — fiscalId duplicado en la empresa.

Ver Errores y validaciones para el formato general de respuestas de error.

Endpoints

MétodoPathoperationIdScopesDescripción
GET/{companyId}/contactsgetContactscontacts:readLista de contactos
GET/{companyId}/contacts/{id}getContactcontacts:readObtener un contacto
GET/{companyId}/contacts/{id}/versionsgetContactVersionscontacts:readVersiones de el contacto
GET/{companyId}/contacts/{id}/versions/{versionId}getContactVersioncontacts:readVersión de el contacto
POST/{companyId}/contactscreateContactcontacts:writeCrear contacto
PUT/{companyId}/contacts/{id}updateContactcontacts:writeActualizar contacto
PUT/{companyId}/contacts/{id}/tagsupdateContactTagscontacts:writeActualizar etiquetas de contacto
DELETE/{companyId}/contacts/{id}deleteContactcontacts:writeBorrar contacto

Scopes

  • contacts:read — Lectura de contactos.
  • contacts:write — Modificación de contactos.

Empieza gratis y factura con flow

Únete a los más de 90.000 negocios que ya gestionan sus facturas de forma rápida y sencilla con FacturaDirecta
Empieza Gratis

Fácil de usar · Sin permanencia · Sin tarjeta de crédito