NewRecurring invoices: `series_id` is optional
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog
Emails

Replace the email configuration of a company

Scopecompanies:write

Replaces 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 is EMAIL_DOMAIN if email_domain_id is sent and ACCOUNT_DEFAULT otherwise. email_domain_id is accepted only with EMAIL_DOMAIN, and local_part is not accepted with BEEL: any other combination answers 422 VALIDATION_ERROR.
  • defaults: omitted, the stored defaults stay as they are. null removes 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 answers 403 FEATURE_NOT_AVAILABLE, and the sender is not changed. The templates accept the variables listed by GET /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 answers 404 EMAIL_DOMAIN_NOT_FOUND; one that is still being registered answers 409 EMAIL_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 answers 422 VALIDATION_ERROR`.
  • Removed email domains: when the email domain a company chose is removed, the company goes back to ACCOUNT_DEFAULT and keeps its local_part.
  • Credentials: it changes the address real invoices are sent from, so it requires a live API key and the companies:write scope. A test API key answers 403 LIVE_CREDENTIAL_REQUIRED. Send an Idempotency-Key so a retry does not repeat the operation.
  • Environment: the configuration belongs to the company and is the same in test and live.

PUT
/v1/companies/{company_id}/email-configuration
AuthorizationBearer <token>

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

company_idstring

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.

Formatuuid

Header Parameters

Idempotency-Key?string

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.

StatusCodeWhen
400INVALID_IDEMPOTENCY_KEYThe key breaks the format rules above.
409IDEMPOTENCY_KEY_PROCESSINGThe first request is still in flight. Wait for the Retry-After seconds (2) and retry with the same key.
409IDEMPOTENCY_KEY_MISMATCHThe key was already used with a different body. Use a new key.
Match^[a-zA-Z0-9_-]+$
Lengthlength <= 255
sender
defaults?

Response 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.