Preview an import of customers into a company
Scopecustomers:writeParses and validates the file without writing anything: no customer is created. It returns
the same per-record outcome the import would produce, so the caller can correct the data
before importing it with POST .../customers/imports.
source: the origin travels in the body, exactly as in the import.
Keys are prefixed beel_sk_, and each one carries the scopes it was created with: a key
short of the scope an operation needs is answered 403. The scope an operation requires
is shown next to its title, and the full catalogue lives in the Scopes reference.
Keys are created from the BeeL dashboard. They are secret credentials: do not share them or commit them to source control.
In: header
Path Parameters
NIF (company) the operation acts on. It is the only source of context: the account that owns it is derived from it, and the BeeL-Active-Company header plays no part. A NIF you do not reach answers 403, and so does a NIF that does not exist, so the existence of a NIF in another account is never disclosed.
uuidFile with the customers to preview, in the format of source
Format of the file being imported. It is required and has no default: a new origin must be declared explicitly, so adding one never changes the meaning of an existing request.
"csv" | "holded"Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://app.beel.es/api/v1/companies/497f6eca-6276-4993-bfeb-53cbbbba6f08/customers/imports/preview" \ -F file="string" \ -F source="csv"{
"success": true,
"data": {
"metadata": {
"total_customers": 10,
"is_dry_run": true,
"processing_time_ms": 450,
"source_type": "CSV_IMPORT",
"filename": "clientes_enero.csv",
"file_size_bytes": 1048576,
"total_rows": 250
},
"customers_validation": [
{
"index": 0,
"customer": {
"legal_name": "Empresa Cliente SL",
"trade_name": "EmpresaCliente",
"nif": "12345678A",
"alternative_id": {
"type": "NIF_IVA",
"number": "string",
"country_code": "st"
},
"address": {
"street": "Calle Mayor, 123",
"number": "123",
"floor": "2º A",
"door": "A",
"postal_code": "28001",
"city": "Madrid",
"province": "Madrid",
"country": "España",
"country_code": "ES"
},
"phone": "+34 612 345 678",
"email": "user@example.com",
"website": "string",
"billing_emails": [
"user@example.com"
],
"contact_person": "María García",
"notes": "string",
"preferred_payment_method": {
"method": "BANK_TRANSFER",
"iban": "ES1234567890123456789012",
"swift": "ABCDESMMXXX",
"payment_term_days": 30
},
"general_discount": 100,
"active": true
},
"customer_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "VALID",
"errors": [
{
"field": "nif",
"value": "12345678X",
"message": "NIF not found in AEAT census",
"code": "CUSTOMER_IDENTIFIER_REQUIRED"
}
],
"warnings": [
{
"field": "email",
"message": "Email not provided, NIF will be used for invoicing"
}
],
"row_number": 15
}
],
"statistics": {
"total_processed": 10,
"valid": 6,
"with_warnings": 2,
"with_errors": 2,
"duplicates": 1,
"invalid_nifs": 1,
"imported": 8,
"success_rate": 0.8,
"importable": 8,
"not_importable": 2
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "MISSING_HEADERS",
"message": "Required headers not found: 'telefono', 'direccion_calle'. Headers found: nombre_fiscal, nif, email",
"details": {
"missing_headers": [
"telefono",
"direccion_calle"
],
"found_headers": [
"nombre_fiscal",
"nif",
"email"
]
}
},
"meta": {
"timestamp": "2026-03-05T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication is required to access this resource"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The provided data is not valid",
"details": {
"field": "specific error message"
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
},
"type": "https://docs.beel.es/errors/INVOICE_NO_LINES",
"title": "INVOICE_NO_LINES",
"detail": "La factura debe tener al menos una línea",
"instance": "/v1/invoices/abc-123"
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The provided data is not valid",
"details": {
"field": "specific error message"
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
},
"type": "https://docs.beel.es/errors/INVOICE_NO_LINES",
"title": "INVOICE_NO_LINES",
"detail": "La factura debe tener al menos una línea",
"instance": "/v1/invoices/abc-123"
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation error",
"details": {
"field_name": "Field is required"
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please try again in 60 seconds."
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "UNSUPPORTED_MEDIA_TYPE",
"message": "Unsupported media type: text/plain. Supported: application/json"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}Download the managed-account import template GET
Downloads the sample CSV that `POST /v1/accounts/imports` expects: the required headers plus one example row, separated by semicolons and written with a UTF-8 byte order mark so that Excel opens it with the accents intact — the same conventions as `GET /v1/templates/customer-import`. - **The example row is deliberately not importable:** its tax id has a valid shape and an impossible check digit, so it is rejected instead of silently provisioning an account. Replace it with your own rows. - **`customers_file`:** the optional second file of that import is **not** a new format; it is the customer import template, unchanged. Download it from `GET /v1/templates/customer-import`. - **Scope:** the file is the same for every credential and does not depend on any account or on any NIF.
Create several customers of a company POST
Creates up to 500 customers of this company (NIF) in a single call. - **Atomic:** if any customer fails validation the whole batch is rejected with `422` `BULK_VALIDATION_ERROR` and nothing is persisted. This is not a partial operation. - **`dry_run`:** with `dry_run=true` the batch is only validated — tax identifiers against the AEAT register, duplicates inside the batch and against the existing customers, field formats — nothing is written and the answer is `200`. With `dry_run=false`, the default, validation is followed by creation and the answer is `201`. - **Report:** both modes return the same per-record report, so a dry run and a real run are read the same way.