Tags
Tags let you categorize and segment entities (transactions, invoices, bills, journal entries, customers, vendors, products, projects, contracts) by custom dimensions like department, project, or location.
Concepts
- Tag Group — A category of tags (e.g., "Department", "Project", "Location")
- Tag — A specific value within a group (e.g., "Engineering", "Q1 Launch")
- Entity Tag — The link between a tag and a specific entity, identified by
model_type+model_id
Tag Groups
Create a Tag Group
curl -X POST "https://api.ondayzero.com/api/v1/tag-groups" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-H "Content-Type: application/json" \
-d '{"name": "Department", "description": "Cost-center segmentation"}'List Tag Groups
curl "https://api.ondayzero.com/api/v1/tag-groups" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"Group names must be unique in a business (409 otherwise). Each group in the response has id, name, description and tag_count; the list is cursor-paginated. GET /api/v1/tag-groups/{tag_group_id} fetches one.
PUT /api/v1/tag-groups/{tag_group_id} updates name and/or description (an empty body is a 400). DELETE /api/v1/tag-groups/{tag_group_id} removes the group and every tag in it, along with those tags' attachments.
Tags
Create a Tag
curl -X POST "https://api.ondayzero.com/api/v1/tags" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "Engineering",
"tag_group_id": "TAG_GROUP_UUID"
}'description (up to 1000 characters) is optional, and so is tag_group_id — ungrouped tags work too, but grouped tags are what segmented reports use. Tag names must be unique across the business, not just within a group (409 otherwise). Each tag in the response has id, name, description, tag_group_id, tag_group_name and usage_count (entities using it).
GET /api/v1/tags/{tag_id} fetches one tag. PUT /api/v1/tags/{tag_id} updates name, description or tag_group_id. DELETE /api/v1/tags/{tag_id} deletes the tag and removes it from every entity.
List Tags
curl "https://api.ondayzero.com/api/v1/tags?tag_group_id=TAG_GROUP_UUID&search=eng" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"search is a fuzzy (trigram) name match. POST /api/v1/tags/suggest with {"context": "SaaS startup, 12 people", "existing_tags": ["Engineering"]} returns AI-suggested tag names as suggestions of {name, reason}; context is optional (up to 500 characters).
Tagging Entities
Attach a Tag
Attaching is idempotent: re-attaching the same tag returns the existing attachment instead of an error. The entity must exist in your business (404 otherwise), and an unsupported model_type is a 400.
curl -X POST "https://api.ondayzero.com/api/v1/entity-tags" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-H "Content-Type: application/json" \
-d '{
"tag_id": "TAG_UUID",
"model_type": "transaction",
"model_id": "ENTITY_UUID"
}'Supported model_type values
transaction, invoice, bill, journal_entry, line_entry, customer, vendor, product, project, contract
View Tags on an Entity
curl "https://api.ondayzero.com/api/v1/entity-tags/transaction/{model_id}" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"The list is cursor-paginated; each item has id, tag_id, tag_name, tag_group_name, model_type, model_id and created_at. For many entities at once, POST /api/v1/entity-tags/batch with {"model_type": "transaction", "model_ids": ["UUID_1", "UUID_2"]} (up to 200 IDs) returns items, a map of entity ID to its tags; entities with no tags are omitted.
Detach a Tag
curl -X DELETE "https://api.ondayzero.com/api/v1/entity-tags/{tag_id}/transaction/{model_id}" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"Bulk Operations
Attach several tags to one entity:
curl -X POST "https://api.ondayzero.com/api/v1/entity-tags/bulk-attach" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-H "Content-Type: application/json" \
-d '{
"model_type": "transaction",
"model_id": "ENTITY_UUID",
"tag_ids": ["TAG_UUID_1", "TAG_UUID_2"]
}'The response has entity_tags (all tags on the entity afterwards), attached_count and total_count. Attach tags to many entities in one call (up to 500 model_ids; existing attachments are skipped):
curl -X POST "https://api.ondayzero.com/api/v1/entity-tags/bulk-attach-many" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-H "Content-Type: application/json" \
-d '{
"model_type": "transaction",
"model_ids": ["UUID_1", "UUID_2", "UUID_3"],
"tag_ids": ["TAG_UUID"]
}'The response has attached_count and entity_count. POST /api/v1/entity-tags/bulk-detach takes the same shape as bulk-attach and removes the tags instead, returning the remaining entity_tags with removed_count and remaining_count.
Find Entities by Tag
curl "https://api.ondayzero.com/api/v1/tags/{tag_id}/entities/transaction?limit=50" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"Returns the tagged entities of that model_type, cursor-paginated, as items of {tag_id, tag_name, model_type, entity_id}. Transaction lists also accept tag_id as a filter directly (GET /api/v1/transactions?tag_id=…).
Tag-Based Reports
Tags power the P&L by Department report. Create a "Department" tag group, tag your transactions, and generate pnl_by_department with tag_group_id (one sheet per tag) or specific tag_ids via the Reports API. pnl_by_department requires the CFO Suite add-on. tag_ids also narrows profit_and_loss and the other income statement reports to the tagged activity.
Common errors
| Status | Cause | Fix |
|---|---|---|
409 |
A tag group or tag with that name already exists in the business (tag names are unique across all groups) | Reuse the existing one, or pick another name |
404 |
The tag, group, or the entity you are tagging does not exist in this business | Check the id and x-business-id |
400 |
Unsupported model_type, or PUT /api/v1/tag-groups/{tag_group_id} with an empty body |
Use a value from the supported list; send name or description |
422 |
A model_ids list longer than 200 (entity-tags/batch) or 500 (bulk-attach-many), or a name over 255 characters |
Split the request |