Embat Attributes API
`Attribute` represents a custom field that you can define once and then use to tag records across Embat, such as an ERP dimension, a cost center or any other analytic field you want available as a filter in tables, charts and reports. `customId` is the unique identifier of an attribute: set your own value to use as your ERP dimension ID, or let Embat auto-generate one. An attribute has a `type` — `list` (a fixed set of `values` to choose from), `string` or `number` (free-form value) — and can optionally be nested under a parent attribute via `parentCustomId` to model hierarchies (e.g. a "City" attribute whose values are nested under a "Country" attribute's values). Attribute values are attached to other entities — `Payments`, `Contacts`, `Operations`, `Transactions` and `AccountingEntries` — by sending the attribute's `customId` together with the chosen `value`/`valueCustomId` in that entity's `attributes` field. **Typical flow:** 1. **Create the attribute** with `POST /attributes/{companyId}`, defining its `type` and, for `list` attributes, its `values`: ```json POST /attributes/{companyId} { "customId": "cost-center", "source": "erp", "name": "Cost Center", "type": "list", "values": [ { "customId": "marketing", "name": "Marketing" }, { "customId": "sales", "name": "Sales" } ] } ``` 2. **Tag other entities with the attribute.** When creating or updating a payment, contact, operation, transaction or accounting entry, reference the attribute in its `attributes` field: ```json { "customId": "marketing", "value": "Marketing" } ``` 3. **Maintain the value list** with `POST /attributes/{companyId}/{customId}/values/bulk` to add values without touching the rest of the attribute, or update the attribute directly to replace its full value list.
Documentation
Specifications
openapi: 3.1.0
info:
title: Embat AccountingAccounts Attributes API
description: Embat API enables connections between any third party application and Embat. Is organized around REST principles, using HTTP responses code and returning data in JSON format. While testing the API, you have to request **sandbox credentials**.
contact:
name: API Support
url: https://embat.io/
email: tech@embat.io
version: 2.120.3
x-logo:
url: https://storage.googleapis.com/embat-production.appspot.com/assets/embat_dark.svg
tags:
- name: Attributes
description: "`Attribute` represents a custom field that you can define once and then use to tag records across Embat, such as an ERP dimension, a cost center or any other analytic field you want available as a filter in tables, charts and reports. `customId` is the unique identifier of an attribute: set your own value to use as your ERP dimension ID, or let Embat auto-generate one.\n\nAn attribute has a `type` — `list` (a fixed set of `values` to choose from), `string` or `number` (free-form value) — and can optionally be nested under a parent attribute via `parentCustomId` to model hierarchies (e.g. a \"City\" attribute whose values are nested under a \"Country\" attribute's values).\n\nAttribute values are attached to other entities — `Payments`, `Contacts`, `Operations`, `Transactions` and `AccountingEntries` — by sending the attribute's `customId` together with the chosen `value`/`valueCustomId` in that entity's `attributes` field.\n\n**Typical flow:**\n\n1. **Create the attribute** with `POST /attributes/{companyId}`, defining its `type` and, for `list` attributes, its `values`:\n\n```json\nPOST /attributes/{companyId}\n{\n \"customId\": \"cost-center\",\n \"source\": \"erp\",\n \"name\": \"Cost Center\",\n \"type\": \"list\",\n \"values\": [\n { \"customId\": \"marketing\", \"name\": \"Marketing\" },\n { \"customId\": \"sales\", \"name\": \"Sales\" }\n ]\n}\n```\n\n2. **Tag other entities with the attribute.** When creating or updating a payment, contact, operation, transaction or accounting entry, reference the attribute in its `attributes` field:\n\n```json\n{\n \"customId\": \"marketing\",\n \"value\": \"Marketing\"\n}\n```\n\n3. **Maintain the value list** with `POST /attributes/{companyId}/{customId}/values/bulk` to add values without touching the rest of the attribute, or update the attribute directly to replace its full value list.\n"
paths:
/attributes/{companyId}:
get:
tags:
- Attributes
summary: List attributes
description: Returns all attributes configured for a company, including their `values` when the attribute is of type `list`.
operationId: list_attributes_attributes__companyId__get
security:
- HTTPBearer: []
parameters:
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/ListAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The requested resource or `companyId` does not exist.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
post:
tags:
- Attributes
summary: Create attribute
description: Creates an attribute. If `customId` is omitted, Embat auto-generates one. If an attribute with the given `customId` already exists, its fields are overwritten instead of raising a duplicate error — this endpoint behaves as an upsert. Sending `values` replaces the attribute's full value list, and **omitting `values` on an existing attribute removes all of its current values** — always resend the values you want to keep.
operationId: create_attribute_attributes__companyId__post
security:
- HTTPBearer: []
parameters:
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PostAttributesRequestSchema'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/UpsertAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Company not found, or `parentCustomId` does not match an existing attribute.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected error. Contact support if it persists.
content:
application/json:
example:
detail: Internal server error
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
patch:
tags:
- Attributes
summary: Update attributes in bulk
description: Updates several attributes in a single call, following the same rules as the single attribute update endpoint. Entries whose `customId` does not match any attribute are silently skipped — the call still returns `200` for the whole batch.
operationId: update_attributes_bulk_attributes__companyId__patch
security:
- HTTPBearer: []
parameters:
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BulkPatchAttributesRequestSchema'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/BulkUpsertAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Company not found, or a `parentCustomId` does not match an existing attribute.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected error. Contact support if it persists.
content:
application/json:
example:
detail: Internal server error
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
delete:
tags:
- Attributes
summary: Delete attributes in bulk
description: Deletes several attributes in a single call, following the same rules as the single attribute deletion endpoint. `customId` values that do not match any attribute still return `200` — no `404` is raised — and each returned `id` is derived from the requested `customId`, so an entry in the response does not confirm that an attribute existed or was removed.
operationId: delete_attributes_bulk_attributes__companyId__delete
security:
- HTTPBearer: []
parameters:
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BulkDeleteAttributesRequestSchema'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/BulkModifyAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The requested resource or `companyId` does not exist.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected error. Contact support if it persists.
content:
application/json:
example:
detail: Internal server error
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/attributes/{companyId}/{customId}:
get:
tags:
- Attributes
summary: Retrieve attribute
description: Returns a single attribute by `customId`.
operationId: retrieve_attribute_attributes__companyId___customId__get
security:
- HTTPBearer: []
parameters:
- name: customId
in: path
required: true
schema:
type: string
title: Customid
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GetAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Company not found, or no attribute matches the given `customId`.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
patch:
tags:
- Attributes
summary: Update attribute
description: Updates an attribute identified by `customId`. Only the fields sent in the request are changed; fields left out keep their current value. If `values` is sent, it **replaces** the attribute's full value list — any previously stored value not included is removed (omit `values` entirely to leave the current values untouched). Updating a `customId` that does not match any attribute returns `200` without applying any change — no `404` is raised.
operationId: update_attribute_attributes__companyId___customId__patch
security:
- HTTPBearer: []
parameters:
- name: customId
in: path
required: true
schema:
type: string
title: Customid
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PatchAttributesRequestSchema'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/UpsertAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Company not found, or `parentCustomId` does not match an existing attribute.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected error. Contact support if it persists.
content:
application/json:
example:
detail: Internal server error
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
delete:
tags:
- Attributes
summary: Delete attribute
description: Deletes an attribute by `customId`, together with all of its values, and clears the `parentId`/`parentCustomId` of any attribute nested under it. Deleting a `customId` that does not match any attribute still returns `200` — no `404` is raised — and the `id` returned in that case is derived from the requested `customId`, so it does not confirm that an attribute existed or was removed.
operationId: delete_attribute_attributes__companyId___customId__delete
security:
- HTTPBearer: []
parameters:
- name: customId
in: path
required: true
schema:
type: string
title: Customid
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/ModifyAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The requested resource or `companyId` does not exist.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected error. Contact support if it persists.
content:
application/json:
example:
detail: Internal server error
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/attributes/{companyId}/bulk:
post:
tags:
- Attributes
summary: Create attributes in bulk
description: Creates several attributes in a single call, following the same rules as the single attribute creation endpoint (upsert by `customId`; omitting `values` on an existing attribute removes all of its current values).
operationId: create_attributes_bulk_attributes__companyId__bulk_post
security:
- HTTPBearer: []
parameters:
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BulkPostAttributesRequestSchema'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/BulkUpsertAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Company not found, or a `parentCustomId` does not match an existing attribute.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected error. Contact support if it persists.
content:
application/json:
example:
detail: Internal server error
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/attributes/{companyId}/{customId}/values/bulk:
post:
tags:
- Attributes
summary: Add values to an attribute
description: Adds values to an existing attribute, identified by `customId`, without affecting its other values. If a value with the same `customId` already exists on the attribute, it is replaced. This endpoint does not verify that the attribute exists beforehand.
operationId: add_attribute_values_attributes__companyId___customId__values_bulk_post
security:
- HTTPBearer: []
parameters:
- name: customId
in: path
required: true
schema:
type: string
title: Customid
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BulkPostAttributesValuesRequestSchema'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/BulkUpsertAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The requested resource or `companyId` does not exist.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected error. Contact support if it persists.
content:
application/json:
example:
detail: Internal server error
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/attributes/{companyId}/{customId}/values:
delete:
tags:
- Attributes
summary: Remove values from an attribute
description: Removes one or more values from an attribute, identified by `customId`. Values not found on the attribute are silently ignored — the call still returns `200`. The `id` returned for each entry is the value's `customId` echoed back, not a generated Embat ID.
operationId: remove_attribute_values_attributes__companyId___customId__values_delete
security:
- HTTPBearer: []
parameters:
- name: customId
in: path
required: true
schema:
type: string
title: Customid
- name: companyId
in: path
required: true
schema:
type: string
title: Companyid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BulkDeleteAttributesRequestSchema'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/BulkModifyAttributesResponseSchema'
'401':
description: Unauthorized. The bearer token is missing, invalid or expired.
content:
application/json:
example:
detail: user not authorized
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found. The requested resource or `companyId` does not exist.
content:
application/json:
example:
detail: 0021 companyId not found
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected error. Contact support if it persists.
content:
application/json:
example:
detail: Internal server error
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
BulkDeleteAttributesRequestSchema:
properties:
data:
items:
$ref: '#/components/schemas/DeleteAttributesRequestSchema'
type: array
title: Data
description: Attributes or values to remove, identified by `customId`.
type: object
required:
- data
title: BulkDeleteAttributesRequestSchema
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
input:
title: Input
ctx:
type: object
title: Context
type: object
required:
- loc
- msg
- type
title: ValidationError
BulkPostAttributesValuesRequestSchema:
properties:
data:
items:
$ref: '#/components/schemas/AttributesRequestValuesSchema'
type: array
title: Data
description: Values to add to the attribute.
type: object
required:
- data
title: BulkPostAttributesValuesRequestSchema
SourceEnum:
type: string
enum:
- erp
- api
- embat
title: SourceEnum
DeleteAttributesRequestSchema:
properties:
customId:
type: string
title: Customid
description: 'Custom ID to remove: the attribute''s `customId` when deleting attributes, or a value''s `customId` when removing values from an attribute.'
type: object
required:
- customId
title: DeleteAttributesRequestSchema
ModifyAttributesResponseSchema:
properties:
id:
type: string
title: Id
description: Embat resource ID
type: object
required:
- id
title: ModifyAttributesResponseSchema
GetAttributesResponseSchema:
properties:
customId:
anyOf:
- type: string
- type: 'null'
title: Customid
description: Your own unique ID for the attribute. If omitted, Embat auto-generates one.
examples:
- cost-center
source:
anyOf:
- $ref: '#/components/schemas/SourceEnum'
- type: 'null'
description: Origin of the attribute record. Defaults to `embat` when not stored on the record.
active:
type: boolean
title: Active
description: Whether the attribute is active.
default: true
name:
type: string
title: Name
description: Display name of the attribute.
examples:
- Cost Center
type:
anyOf:
- $ref: '#/components/schemas/AttributesStatusEnum'
- type: 'null'
description: 'Data type of the attribute''s values: `list`, `string` or `number`.'
required:
type: boolean
title: Required
description: 'Whether a value for this attribute should be mandatory wherever it is used. Informational only: this API does not enforce it.'
default: false
values:
anyOf:
- items:
$ref: '#/components/schemas/AttributesResponseValuesSchema'
type: array
- type: 'null'
title: Values
description: Values available for this attribute.
parentCustomId:
anyOf:
- type: string
- type: 'null'
title: Parentcustomid
description: Custom ID of the parent attribute this attribute is nested under.
id:
type: string
title: Id
description: Embat attribute ID.
createdAt:
type: string
format: date-time
title: Createdat
description: Creation date of the attribute.
updatedAt:
type: string
format: date-time
title: Updatedat
description: Last modification date of the attribute.
parentId:
anyOf:
- type: string
- type: 'null'
title: Parentid
description: Embat ID of the parent attribute. Only present when the attribute is nested under another one via `parentCustomId`.
companyId:
type: string
title: Companyid
description: Embat company ID. You can get them from "companies" endpoints
type: object
required:
- name
- id
- createdAt
- updatedAt
- companyId
title: GetAttributesResponseSchema
BulkPostAttributesRequestSchema:
properties:
data:
items:
$ref: '#/components/schemas/PostAttributesRequestSchema'
type: array
title: Data
description: Attributes to create.
type: object
required:
- data
title: BulkPostAttributesRequestSchema
BulkModifyAttributesResponseSchema:
properties:
data:
items:
$ref: '#/components/schemas/ModifyAttributesResponseSchema'
type: array
title: Data
description: Result of the bulk operation, one entry per item.
type: object
required:
- data
title: BulkModifyAttributesResponseSchema
UpsertAttributesResponseSchema:
properties:
id:
type: string
title: Id
description: Embat resource ID
customId:
type: string
title: Customid
description: Client-provided custom ID
type: object
required:
- id
- customId
title: UpsertAttributesResponseSchema
ListAttributesResponseSchema:
properties:
data:
items:
$ref: '#/components/schemas/GetAttributesResponseSchema'
type: array
title: Data
description: All attributes of the company.
type: object
required:
- data
title: ListAttributesResponseSchema
AttributesStatusEnum:
type: string
enum:
- list
- string
- number
title: AttributesStatusEnum
AttributesResponseValuesSchema:
properties:
customId:
anyOf:
- type: string
- type: 'null'
title: Customid
description: Your own unique ID for the value. If omitted, Embat auto-generates one.
examples:
- madrid
id:
type: string
title: Id
description: Embat ID of the value.
name:
type: string
title: Name
description: Display name of the value.
examples:
- Madrid
parentCustomId:
anyOf:
- type: string
- type: 'null'
title: Parentcustomid
description: Custom ID of the value, within the parent attribute (see the attribute's `parentCustomId`), that this value is nested under.
examples:
- spain
parentId:
anyOf:
- type: string
- type: 'null'
title: Parentid
description: Embat ID of the parent value. Only present when `parentCustomId` matched an existing value of the parent attribute at the time this value was saved.
type: object
required:
- id
- name
title: AttributesResponseValuesSchema
AuxBulkPatchAttributesRequestSchema:
properties:
name:
anyOf:
- type: string
- type: 'null'
title: Name
description: Display name of the attribute.
active:
type: boolean
title: Active
description: Whether the attribute is active. Omit to leave the current value unchanged.
default: true
values:
anyOf:
- items:
$ref: '#/components/schemas/AttributesRequestValuesSchema'
type: array
- type: 'null'
title: Values
description: 'Full list of values the attribute should have after this update. Sending `values` **replaces** the current list: any previously stored value whose `customId` is not included here is removed. Omit `values` entirely to leave the current values untouched. An attribute holds at most 5000 values; if the combined total would exceed the limit, the excess new values are silently discarded and existing ones already in the list are kept.'
parentCustomId:
anyOf:
- type: string
- type: 'null'
title: Parentcustomid
description: Custom ID of the parent attribute, to nest this attribute under another one (e.g. a "City" attribute nested under "Country"). Must reference an existing attribute.
examples:
- country
customId:
type: string
title: Customid
description: Custom ID of the attribute to update.
examples:
- cost-center
type: object
required:
- customId
title: AuxBulkPatchAttributesRequestSchema
PatchAttributesRequestSchema:
properties:
name:
anyOf:
- type: stri
# --- truncated at 32 KB (37 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/embat/refs/heads/main/openapi/embat-attributes-api-openapi.yml