NewProvince is only required for addresses in Spain
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog
Accounts

Provision an account

Scopeaccounts:write

Provisions a new account on BeeL and, when it is born with a holder, returns a single-use claim_token to deliver so they can set a password and take ownership.

  • email: send it to create the account with a holder. Omit it and the account is created with no person at all, no person_id and no claim_token; a holder can be added later with POST /v1/accounts/{account_id}/claim-tokens.
  • tax_profile: send it and the account comes back ready to invoice, with its NIF, default invoice series and VeriFactu configuration set up. Omit it and the account's company is created without a NIF until its holder registers one. Either way its company_id is in the response.
  • access_level: the access you retain over the account. Defaults to NONE; OPERATE requires a tax_profile.
  • external_ref: the idempotency key. Resending the same one returns the existing account rather than creating a second.
  • Entitlement: requires manage_accounts.

Reactivation

If you previously ended your management of this account (DELETE /v1/accounts/{account_id}/management) and its holder has not claimed it yet, provisioning the same email reactivates that account instead of creating a new one. The same account, holder, NIFs and invoices come back under your management, with the external_ref and access_level of this request, and it counts towards your billable usage again. Once the holder has claimed the account it is theirs, and only they can grant you access again.


POST
/v1/accounts
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

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
email?string

Optional. Email address of the account holder, used as their login. Omit it to create the account without a person: no login, no person_id and no claim_token. You can add the holder later with POST /v1/accounts/{account_id}/claim-tokens. Required when send_email is true (there is nobody to write to otherwise) — else 422.

Formatemail
display_namestring

Human-readable name for the account. Must not be blank.

Length1 <= length <= 255
external_refstring

Your own identifier for this account in your system. Used as an idempotency key: re-provisioning with the same external_ref returns the existing account (201, not 409).

language?string
Value in"es" | "en" | "ca"
access_level?string
Value in"NONE" | "VIEW" | "OPERATE"
tax_profile?
send_email?boolean

Optional. When true, BeeL emails the account holder a claim link (/reclamar?token=...) so they can set their password and take ownership. Defaults to false: by default you receive the claim_token in the response and deliver it yourself. Requires a deliverable email: sending true without one returns 422.

Defaultfalse

Response Body

application/json

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/accounts" \  -H "Content-Type: application/json" \  -d '{    "email": "hola@estudio-ejemplo.example.com",    "display_name": "Estudio Ejemplo",    "external_ref": "cliente-4821",    "language": "es",    "access_level": "OPERATE",    "tax_profile": {      "nif": "12345678Z",      "legal_name": "María López Fernández",      "entity_type": "INDIVIDUAL",      "address": {        "street": "Calle Mayor",        "number": "15",        "floor": "2",        "door": "B",        "postal_code": "28013",        "city": "Madrid",        "province": "Madrid",        "country_code": "ES"      },      "default_main_tax": {        "type": "IVA",        "percentage": 21,        "regime_key": "01"      },      "default_irpf_rate": 15    },    "send_email": false  }'
{
  "success": true,
  "data": {
    "person_id": "087e858e-473c-4f50-b5b0-c1df6c021550",
    "account_id": "449e7a5c-69d3-4b8a-aaaf-5c9b713ebc65",
    "status": "PROVISIONED",
    "claim_token": "string",
    "claim_url": "http://example.com",
    "claim_link_already_issued": false,
    "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf"
  },
  "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": "FORBIDDEN",
    "message": "You do not have permission 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": "PROVISIONING_TAX_PROFILE_REQUIRED",
    "message": "With access_level OPERATE you must send tax_profile: invoicing on the account's behalf needs its NIF."
  },
  "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": "EXTERNAL_SERVICE_ERROR",
    "message": "A technical error occurred. Please try again later.",
    "details": {}
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00Z",
    "request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  },
  "type": "https://docs.beel.es/errors/EXTERNAL_SERVICE_ERROR",
  "title": "EXTERNAL_SERVICE_ERROR",
  "detail": "A technical error occurred. Please try again later.",
  "instance": "/api/v1/accounts"
}
{
  "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"
  }
}