Set the default email domain
Scopeemail-domains:writeMakes this domain the one the account's emails are sent from by default, and clears the flag on the domain that had it, so the account always has at most one default.
- Repeatable: it states the desired default rather than performing a change, so
repeating the call on the domain that already is the default returns the same
200. - Any status: a domain can be the default while it is still
PENDINGorFAILED. Emails only leave from it once it isVERIFIED; until then they go out from BeeL. - Without the add-on: it works, so an account can still choose among the domains it holds.
- Credentials: it changes the real account, so it requires a live API key or a dashboard
session. A test API key answers
403 LIVE_CREDENTIAL_REQUIRED. Send anIdempotency-Keyso a retry does not repeat the operation.
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
Your own account, or an account you provisioned. The account in the path, not the credential, decides which account the operation acts on. A 403 is returned when you do not reach it, the same response an account that does not exist gets.
uuidIdentifier of the email domain.
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
curl -X PUT "https://app.beel.es/api/v1/accounts/497f6eca-6276-4993-bfeb-53cbbbba6f08/email-domains/497f6eca-6276-4993-bfeb-53cbbbba6f08/default"{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"domain": "facturas.ejemplo.com",
"status": "VERIFIED",
"is_default": true,
"dns_records": [
{
"type": "MX",
"name": "send",
"value": "mail.example.com",
"priority": 10,
"status": "VERIFIED"
}
],
"created_at": "2025-01-20T14:30:00Z",
"verified_at": "2025-01-20T15:10:00Z",
"last_checked_at": "2025-01-20T15:10:00Z"
},
"meta": {
"timestamp": "2025-01-20T15:30:00Z",
"request_id": "req_123"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The parameter 'invoice_id' has an invalid type. Expected: UUID.",
"details": {
"field": "invoice_id",
"invalid_value": "deliveries",
"expected_format": "UUID"
}
},
"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": "EMAIL_DOMAIN_NOT_FOUND",
"message": "No email domain with that id belongs to your account."
},
"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"
}
}Verify an email domain POST
Asks for the DNS records of the domain to be checked, once you have published them. The check is asynchronous: the call returns `202` with the domain as it is now, usually still `PENDING`, and its `status` changes to `VERIFIED` or `FAILED` when the check finishes. Read the domain with `GET` to see the result. A domain that is not `VERIFIED` 72 hours after it was registered is removed and its name is freed. - **Add-on:** requires the custom email domain add-on, which is contracted with BeeL. Without it the call answers `403 FEATURE_NOT_AVAILABLE`. - **`EMAIL_DOMAIN_NOT_READY` (`409`):** the domain is still registering (`dns_records: []`); repeat the call in a few seconds. - **Sending service failure:** if the check cannot be requested the call fails with `502` and nothing changes. - **Unpaid billing:** when the billing of the account is unpaid the call answers `402 PAYMENT_REQUIRED`. - **Credentials:** it requires a live API key or a dashboard session. A test API key answers `403 LIVE_CREDENTIAL_REQUIRED`. Send an `Idempotency-Key` so a retry does not repeat the operation.
Remove an email domain DELETE
Removes the domain from your account and from the email sending service, which frees the name so it can be registered again. The account's emails stop being sent from it. - **Without the add-on:** it works, so you can clean up what the account still holds. - **Default domain:** removing the default leaves the account without one; its emails go out from BeeL until you set another. - **Name:** the name is free for a new registration as soon as the call returns. If the removal in the sending service fails afterwards, an immediate new registration of the same name may answer `EMAIL_DOMAIN_UNAVAILABLE` for a while. - **Still registering:** a domain that stays `PENDING` with `dns_records: []` is removed this way. - **Credentials:** it changes the real account, so it requires a live API key or a dashboard session. A test API key answers `403 LIVE_CREDENTIAL_REQUIRED`. Send an `Idempotency-Key` so a retry does not repeat the operation.