Unified contacts
Migrate client and supplier integrations without losing fiscal identity or history.
Availability and identity
Use /v1/contacts for new integrations. One contact can be both a customer and a supplier without duplicating its fiscal identity. Access still follows the authenticated company and the key’s contacts:* scopes; roles do not replace user permissions.
A contact has one fiscal identity and an opaque UUID in id. Its cumulative roles are customer, supplier and lead, each with active or inactive status. A fiscal lead still requires a valid tax ID or alternative fiscal identification; prefiscal capture and CRM opportunities are separate future capabilities. Assign customer to the existing contact when it becomes a customer instead of creating a duplicate. Roles never grant user permissions.
Create a customer or supplier contact
Use name, kind and an explicit roles array. Writes use role strings; reads return role objects with status and dates. The same id is reused for every role.
curl -X POST https://api.factuarea.com/v1/contacts \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"name":"Distribuciones Ejemplo SL","kind":"company","tax_id":"B12345674","roles":["customer","supplier"]}'Read and filter
Use GET /v1/contacts with search for name, tax ID, email, phone/mobile or external reference. Use roles, role_match, role_status, kind, country_code, province, city, tags, has_email, has_phone and creation dates for structured filters. Pagination uses limit and starting_after; read has_more before continuing.
Use GET /v1/contacts/options to obtain available filter values. field=country returns the country catalog; country_code, province, city and tag return values present in that company's contacts. Country codes use ISO alpha-2. Province and city are exact matches, not arbitrary substring filters. Tags are normalized and tenant-specific.
Write without losing settings
Create with POST /v1/contacts, including an explicit roles array (which may be empty). Update shared identity separately from role transitions, customer/supplier profiles and bank accounts. Preserve both profiles for dual-role contacts. Customer price-list defaults belong to customer_profile.default_price_list_uuid; purchase defaults belong to the supplier profile. Use UUID values, not internal numeric IDs.
Archiving is not deletion of fiscal history. Deactivation preserves document associations but blocks selecting that role for new operations. Removing a referenced role is rejected; use deactivation instead. Follow the operation's scope and idempotency requirements in the API reference.
Documents, recurring invoices and automation
Sales invoices, quotes, delivery notes and proformas resolve the customer identity. Purchase invoices, supplier offers/products and contracts resolve the supplier identity. Keep historical associations when roles become inactive. Recurring schedules are separate from issued invoices: a schedule is not invoiced revenue, and generated invoices must remain linked to the canonical contact. Existing schedules and historical document associations remain linked during migration.
The public API exposes only /v1/contacts for third-party identities. Store the contact UUID returned by this API and preserve historical document snapshots. Subscribe to contact events explicitly and deduplicate deliveries using event identity.
SDKs, CLI and tools
The SDK exposes the contacts resource; the CLI exposes contacts commands. MCP exposes the same contact operations with contacts:read, contacts:write or contacts:delete scopes. Check that your installed client version includes them before migrating. The conversational assistant reads canonical contacts and opens the contact UI for writes; it does not silently invent a CRM pipeline.
Manage roles, profiles, archiving and deletion
Assign roles with POST /v1/contacts/{contact}/roles/{role}. Change a role’s status with PUT /v1/contacts/{contact}/roles/{role}/status; include role and status in the body. Remove only unreferenced roles with DELETE /v1/contacts/{contact}/roles/{role}.
Update shared identity with PUT /v1/contacts/{contact}. Update defaults through /customer-profile or /supplier-profile, and bank accounts through /bank-accounts; these are PUT operations. Inactive roles and archived contacts retain their history.
POST /v1/contacts/{contact}/archive archives the contact and PUT /v1/contacts/{contact}/restore brings it back; archiving is always allowed, even when the contact has invoices, contracts or supplier offers. DELETE /v1/contacts/{contact} is a different operation: a soft delete that removes the contact from every read surface and cannot be undone through the API, while its documents stay intact. Use the returned is_archived to offer the appropriate action; archive and role status are different states. List archived records with GET /v1/contacts?is_archived=1.
Document identifiers
The document contract still names the directional fields client_id and supplier_id. Supply the canonical contact id with an active customer or supplier role respectively. Do not rename these request fields to contact_id. The server resolves the directional projection within the authenticated company.
Import
Use the contact import preview to review roles, identity conflicts and field mappings before a bulk import. Use POST /v1/contacts/census-verification to verify a Spanish name and tax-ID pair without creating a contact.