Provision an account
Scopeaccounts:writeProvisions 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, noperson_idand noclaim_token; a holder can be added later withPOST /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 itscompany_idis in the response.access_level: the access you retain over the account. Defaults toNONE;OPERATErequires atax_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.
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 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 <= 255Optional. 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.
emailHuman-readable name for the account. Must not be blank.
1 <= length <= 255Your 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).
"es" | "en" | "ca""NONE" | "VIEW" | "OPERATE"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.
falseResponse 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"
}
}Get the fiscal summary of a company GET
Returns the VAT and IRPF summary of the invoices issued under this company over the requested period, together with the annual IRPF projection and its progressive bracket breakdown. `start_date` and `end_date` go together: send both, or neither. Omitting both defaults to the current month; sending only one answers `400`, because a period you did not ask for is worse than an error. The range may not exceed 365 days, and every fault names itself in `details.reason`.
Issue a claim token POST
Issues a single-use `claim_token`, and the `claim_url` built from it, so the account's holder can set a password and take ownership. - **`email`:** send it when the account has no holder yet — the person is created by this call. Omit the body to re-issue the token for the holder the account already has. An `email` that differs from the existing holder's is rejected rather than replacing them. - **Lifetime:** tokens last 30 days, and only the last one issued is live. Issuing again invalidates the previous token, so the old link stops working the moment you ask for a new one. - **Not an invitation:** this hands the account itself over to its holder. To add a further person to an account that already has one, invite them with `POST /v1/accounts/{account_id}/invitations`. - **Entitlement:** requires `manage_accounts`.