Replace the email configuration of a company
Scopecompanies:writeReplaces the sender chosen for the invoice emails of the company, and optionally their
defaults. It does not affect other emails. The sender is a replacement, not a merge: a
property that is omitted or null goes back to its default, which is to inherit the default
email domain of the account and to use facturas as the local_part. The response is the
configuration as it is after the change, including the address in effect.
sender.source: when omitted it isEMAIL_DOMAINifemail_domain_idis sent andACCOUNT_DEFAULTotherwise.email_domain_idis accepted only withEMAIL_DOMAIN, andlocal_partis not accepted withBEEL: any other combination answers422VALIDATION_ERROR.defaults: omitted, the stored defaults stay as they are.nullremoves them. An object replaces all of them, so a property left out of it is removed. Sending an object requires the email customization plan: without it the call answers403FEATURE_NOT_AVAILABLE, and the sender is not changed. The templates accept the variables listed byGET /v1/email-template-variables.email_domain_id: an email domain of the account that has already been registered. A domain that does not exist, belongs to another account or was removed answers404EMAIL_DOMAIN_NOT_FOUND; one that is still being registered answers409EMAIL_DOMAIN_NOT_READY. Choosing a domain that is not verified is allowed: until it is verified, invoice emails go out from the default email domain of the account if that one is verified, and from BeeL. otherwise.local_part: up to 64 characters: lowercase letters, digits and the symbols!#$%&'*+/=?^_\{|}~-, with single dots between groups. Any other value answers422VALIDATION_ERROR`.- Removed email domains: when the email domain a company chose is removed, the company
goes back to
ACCOUNT_DEFAULTand keeps itslocal_part. - Credentials: it changes the address real invoices are sent from, so it requires a live
API key and the
companies:writescope. A test API key answers403LIVE_CREDENTIAL_REQUIRED. Send anIdempotency-Keyso a retry does not repeat the operation. - Environment: the configuration belongs to the company and is the same in test and live.
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
Unique identifier (UUID) of the company the operation acts on: its identifier, not its NIF. 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 company you do not reach answers 403, and so does a company that does not exist, so the existence of a company in another account is never disclosed.
uuidHeader Parameters
Idempotency key to prevent duplicates in sensitive operations.
- Any unique client-generated string (e.g. an order id). A UUID also works but is not required
- Allowed characters: letters, digits,
_and-(max 255 chars) - Retrying with the same key replays the first response when it was a success (2xx) or a
server error (5xx): same status and body, plus the header
Idempotency-Replay: true. After a 5xx, check whether the operation took effect before retrying with a new key - A 4xx is not stored: the key is released, so the corrected request can reuse it
- Stored responses expire 24 hours after processing
The key is scoped per user and environment, and bound to the request body, so retrying after a network timeout replays the stored response instead of repeating the operation.
| Status | Code | When |
|---|---|---|
400 | INVALID_IDEMPOTENCY_KEY | The key breaks the format rules above. |
409 | IDEMPOTENCY_KEY_PROCESSING | The first request is still in flight. Wait for the Retry-After seconds (2) and retry with the same key. |
409 | IDEMPOTENCY_KEY_MISMATCH | The key was already used with a different body. Use a new key. |
^[a-zA-Z0-9_-]+$length <= 255Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X PUT "https://app.beel.es/api/v1/companies/497f6eca-6276-4993-bfeb-53cbbbba6f08/email-configuration" \ -H "Content-Type: application/json" \ -d '{ "sender": { "source": "EMAIL_DOMAIN", "email_domain_id": "550e8400-e29b-41d4-a716-446655440000", "local_part": "cobros" }, "defaults": { "subject": "Invoice {invoiceNumber}", "message": "Dear {customerName}, please find attached invoice {invoiceNumber}.", "cc": [ "administracion@ejemplo.com" ] } }'{
"success": true,
"data": {
"sender": {
"source": "ACCOUNT_DEFAULT",
"email_domain_id": "b3a00cb4-43d0-468a-8a5d-50c998cb143f",
"local_part": "cobros",
"effective": {
"from_address": "facturas@facturas.ejemplo.com",
"reason": "CUSTOM_DOMAIN",
"email_domain_id": "550e8400-e29b-41d4-a716-446655440000"
}
},
"defaults": {
"subject": "Invoice {invoiceNumber}",
"message": "Dear {customerName}, please find attached invoice {invoiceNumber}.",
"cc": [
"user@example.com"
],
"additional_recipients": [
"user@example.com"
]
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "Invalid request"
},
"meta": {
"timestamp": "2025-01-15T10: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": "The invoice must have at least one line",
"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": "The invoice must have at least one line",
"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": "The invoice must have at least one line",
"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": "The invoice must have at least one line",
"instance": "/v1/invoices/abc-123"
}{
"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"
}
}Get the email configuration of a company GET
Returns the address the invoice emails of the company are sent from and the defaults that apply when an invoice is sent by email. It applies only to invoice emails. - **`sender.source`, `sender.email_domain_id` and `sender.local_part`:** what the company chose. A `local_part` that is `null` means `facturas`. - **`sender.effective`:** the address the next invoice email will go out from, and why (`reason`). With `source` `BEEL` it is the address of BeeL. Otherwise it is resolved in this order: the email domain chosen by the company and the default email domain of the account, then the address of BeeL. Only email domains that are verified, and only while the account holds the custom email domain add-on, count. The add-on is contracted with BeeL. `email_domain_id` is present only when the address uses one of the account's email domains. - **`defaults`:** the content applied to an invoice email that does not specify its own. Each property is `null` when it is not set. - **Domain no longer verified:** invoice emails go out from BeeL. without interruption, and `reason` reports it. - **Environment:** the configuration belongs to the company and is the same in test and live.
List the variables of the email templates GET
Returns the placeholders that the `subject` and `message` of the email templates accept, such as `defaults.subject` in `GET /v1/companies/{company_id}/email-configuration`. Write a placeholder, braces included, wherever the value should appear: it is replaced when the email is sent. - **Scope:** the catalogue is the same for every credential and does not depend on any account or company, so the operation takes no identifier. - **Unknown placeholders:** a placeholder that is not listed is sent as written. **Closed catalogue.** This collection is fixed and bounded: it carries no `pagination`, it takes no `page`/`limit`, and every response holds the whole set.