Create or update a custom field of a company
Scopecustom-fields:writeCreates the custom field with this key, or updates it if the company already has one.
Repeating the request leaves the same state, so it is safe to run on every deployment to
seed a catalogue.
- Status:
201when the field is created,200when it already existed. - Key: it is the path, never the body, and it never changes. To stop using a field,
archive it (
is_archived: true); fields are never deleted. - Archive state: omitting
is_archivedkeeps the current one, so repeating the request never reactivates a field someone archived. - Suggestions: omitting
suggest_valueskeeps the current setting; a new field starts withtrue. Usefalsefor a value that changes on every invoice, such as an order number: invoices store the text as sent and no options are created. Turning it off deletes no option, and turning it back on offers them again. - Options: the response carries the common options of the field, or none when
suggest_valuesisfalse.
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 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.
uuidKey of the custom field: lowercase letters, digits and _, up to 64 characters. A key outside that format answers 422.
^[a-z0-9_]{1,64}$1 <= length <= 64Header 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 <= 255Name people see next to the value. Leading and trailing spaces are removed; a label that is empty after that answers 422.
1 <= length <= 100Whether the PDF of invoices saved from now on prints this field.
true offers the values already used as options and adds new ones as invoices are saved; false stores each value as sent and creates no options. Omit it to keep the current setting; a new field starts with true. Turning it off deletes no option.
true archives the field, false reactivates it. Omit it to keep the current state.
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/custom-fields/store" \ -H "Content-Type: application/json" \ -d '{ "label": "Store", "show_on_pdf": true }'{
"success": true,
"data": {
"id": "7d2f8a40-3c1e-4b6a-9f0d-2e5b8c1a4d77",
"key": "store",
"label": "Store",
"show_on_pdf": true,
"suggest_values": true,
"is_archived": false,
"options": [
{
"id": "0b6c1e2f-5a4d-4c3b-8e7f-1a2b3c4d5e6f",
"value": "Online store",
"customer_id": null,
"is_archived": false
},
{
"id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
"value": "Gran Vía 12",
"customer_id": "4f244735-980b-4d9c-80e8-6331fa0b1958",
"is_archived": false
}
]
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": true,
"data": {
"id": "7d2f8a40-3c1e-4b6a-9f0d-2e5b8c1a4d77",
"key": "store",
"label": "Store",
"show_on_pdf": true,
"suggest_values": true,
"is_archived": false,
"options": [
{
"id": "0b6c1e2f-5a4d-4c3b-8e7f-1a2b3c4d5e6f",
"value": "Online store",
"customer_id": null,
"is_archived": false
},
{
"id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
"value": "Gran Vía 12",
"customer_id": "4f244735-980b-4d9c-80e8-6331fa0b1958",
"is_archived": false
}
]
},
"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": "CONCURRENT_MODIFICATION",
"message": "The resource was modified by another request; read it again and retry"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The provided data is not valid.",
"details": {
"legal_name": "The field 'legal_name' cannot be empty",
"recipient.address.postal_code": "Contains invalid characters."
}
},
"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"
}
}