Open an authorization to connect a payment provider
Scopepayment-connections:writeOpens an authorization session so the holder of a company your account manages
can connect a payment provider (stripe), and returns the authorization_url where they
authorize it.
return_url: once the holder authorizes, BeeL's callback finalizes the connection and redirects back to thereturn_urlof your portal, if you supplied one, with the parameters described underreturn_url.- When the connection appears: it is created only when the holder authorizes, so it
does not appear in
GET /v1/companies/{company_id}/payment-connectionsuntil then. It is sealed under the NIF in the path, so auto-invoicing issues under that NIF. - The NIF must be activated in the mode of your API key (
beel_sk_test_*→ Test,beel_sk_live_*→ Live); otherwise the request answers400COMPANY_NOT_ACTIVATED_IN_ENVIRONMENTand noauthorization_urlis issued, because without activation there is no invoice series or tax configuration to invoice with. Test and Live activations are independent — a NIF activated in one mode still needs activating in the other. - One provider account, one NIF: a provider account (
acct_...) can be connected to a single NIF across the whole platform. Authorizing the same provider account from a second NIF does not move it: the callback fails withOAUTH_ACCOUNT_CONNECTED_TO_OTHER_COMPANY, and the existing connection keeps invoicing under the NIF it was sealed with. To move it, firstDELETE /v1/companies/{company_id}/payment-connections/{connection_id}on the NIF that holds it, then open a new authorization on the NIF you want it under.
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 authorization is opened for — 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.
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 <= 255Payment provider slug in lowercase. Currently only stripe (Stripe Connect) is
operative; woocommerce and shopify are reserved for future providers. Any other
value answers 422.
URL of your portal to redirect the account holder back to after the OAuth callback
completes. Must be an absolute https:// URL. On success BeeL appends
status=success, provider (slug), company_id, connection_id and account
(the provider account id, e.g. acct_...). On error it appends status=error,
provider and message, always a stable uppercase error code: OAUTH_STATE_INVALID
(the authorization is unknown, expired or already used), OAUTH_TOKEN_EXCHANGE_FAILED
(the provider rejected the code exchange), ACCESS_DENIED (the account holder declined
at the provider), OAUTH_ACCOUNT_CONNECTED_TO_OTHER_COMPANY (the provider account is
already connected to another NIF; disconnect it there first),
PROVIDER_ERROR (any other provider-reported failure) or
OAUTH_UNEXPECTED. When omitted, the callback redirects to BeeL's default integrations
screen. A return_url that is not an absolute https:// URL with a host is rejected
up front with 422 PAYMENT_RETURN_URL_INVALID, and no authorization is opened.
^https://.*Response Body
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/companies/497f6eca-6276-4993-bfeb-53cbbbba6f08/payment-connections/authorizations" \ -H "Content-Type: application/json" \ -d '{ "provider": "stripe", "return_url": "https://app.example.com/integrations/stripe/done" }'{
"success": true,
"data": {
"authorization_url": "http://example.com"
},
"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": "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": "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"
}
}Cancel the fiscal representation (deprecated) DELETE
Deprecated predecessor of `DELETE /v1/companies/{company_id}/representation`. It cancels the same representation, but answers `200` with a body where the canonical route answers `204`. **Retires on 9 December 2026.** See the [migration guide](https://docs.beel.es/changelog/resources-under-the-nif) for what moved where and what changes when you switch.
List the payment connections of a NIF GET
Returns the payment provider connections of a company your account **owns or manages**, with the provider-side account each one points at and its `status`. Use it to check whether a NIF you provisioned has completed its connection. - **A NIF with no connections:** answers `200` with an empty list. - **`environment`:** Test and Live connections are independent, so only the ones living in the mode of the key you ask with are returned; this field states which. **Closed catalogue.** A NIF is not limited to one connection per provider: within a single environment it may hold several of the same provider, one per external account. What is unique is the external account itself — one live connection per provider, environment and external account. The set is still bounded and unpaginated: the collection carries no `pagination` and takes no `page`/`limit`, and every response holds the whole set for the environment of the key you ask with.