Custom Tags
Custom tags let you attach your own labels to Flowcase records: CVs (résumés), reference projects, customers and users. Each tag has a name (called its "value") that can be translated into several languages, and belongs to exactly one category.
This guide covers managing categories and tags in Masterdata, then attaching them to CVs, customers and reference projects.
All requests need an Authorization header, and requests with a body need Content-Type: application/json. See Authentication & Security for details.
Overview
Custom tags add extra metadata to CVs, reference projects and customers. They are grouped into categories to help organise them.
- Tag value: the label of the tag in each language, for example
{"int": "Full time employee", "no": "Fast ansatt"} - Category: a grouping for related tags, for example "Employment Type"
- Internationalisation: both tags and categories hold a value per language
- External IDs: optional identifiers that link a tag or category to a record in another system
An internationalised tag looks like this:
{
"values": {
"int": "Full time employee",
"no": "Fast ansatt"
},
"external_unique_id": "HR_SYSTEM:EMPLOYMENT_TYPE"
}
The values object uses legacy language codes by default (int for English, no for Norwegian). Pass use_legacy_codes=false on the Masterdata endpoints below to use ISO 639-1 codes (en, no) instead. See Country & Language Codes for the full list.
Tags on users work differently: you set them with the Users API rather than with a dedicated tag endpoint. See Custom tags in the user synchronisation guide.
Tag categories
Categories group custom tags so you can categorise them in a meaningful way, such as by department, skill or any other criterion.
- Every tag must belong to exactly one category.
- Categories control where their tags can be used (CVs, reference projects, customers).
- Categories hold a value per language, the same as tags.
A category has these fields:
| Field | Description |
|---|---|
id |
Unique identifier for the category. |
values |
The category name per language code. |
external_unique_id |
Optional identifier linking the category to an external system. null or an empty string when not set. |
can_be_used_for_cvs |
Whether tags in this category can be attached to CVs / résumés. |
can_be_used_for_references |
Whether tags in this category can be attached to reference projects. |
can_be_used_for_customers |
Whether tags in this category can be attached to customers. |
allow_filtering |
Whether the category is available as a filter option in the Flowcase UI. |
lock_for_integrations |
When true, only administrators and API integrations can add or remove tags from this category. |
custom_tags |
The tags belonging to this category. |
Example structure
Here is an example showing how tags are organised within categories:
| Category | Category External ID | Tag Value | Tag External ID |
|---|---|---|---|
| int: Employment Type no: Ansettelsestype |
HR.FIELD.EMP_TYPE | int: Full time employee no: Fast ansatt |
HR.FIELD.EMP_TYPE.FULL |
| int: Employment Type no: Ansettelsestype |
HR.FIELD.EMP_TYPE | int: Part time employee no: Deltidsansatt |
HR.FIELD.EMP_TYPE.PART |
| int: Security Clearance no: Sikkerhetsklarering |
HR.FIELD.SEC_LEVEL | int: Level 1 no: Nivå 1 |
HR.FIELD.SEC_LEVEL.L1 |
| int: Security Clearance no: Sikkerhetsklarering |
HR.FIELD.SEC_LEVEL | int: Level 2 no: Nivå 2 |
HR.FIELD.SEC_LEVEL.L2 |
Listing tag categories
Retrieves all tag categories in your organisation. Use this endpoint to get an overview of how tags are organised and what restrictions apply to each category. The response holds both the category definitions and their tags.
Request
Substitute the correct <subdomain> for your company.
GET https://<subdomain>.flowcase.com/api/v1/masterdata/custom_tags/custom_tag_category
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
language_code |
string | optional | Sorts categories and their tags alphabetically by name in this language. Falls back to the language of the authenticated user if omitted. |
use_legacy_codes |
string | optional | Language code format in values. Default true, which returns legacy codes such as int, se and cn. Set to false for ISO 639-1 codes such as en, sv and zh. |
Response
The response is a bare JSON array holding every category in the account, with no pagination envelope. An empty array is returned when the account has no categories.
[
{
"id": "CUSTOM_TAG_CATEGORY_ID_1",
"values": { "int": "NAME", "no": "NAME" },
"external_unique_id": "EXTERNAL_UNIQUE_ID",
"can_be_used_for_cvs": true,
"can_be_used_for_references": true,
"can_be_used_for_customers": true,
"allow_filtering": false,
"custom_tags": [
{
"id": "CUSTOM_TAG_ID_1",
"values": { "int": "NAME", "no": "NAME" },
"external_unique_id": "EXTERNAL_UNIQUE_ID",
"custom_tag_category_id": "CUSTOM_TAG_CATEGORY_ID_1"
// Some fields omitted
}
// More custom tags
]
// Some fields omitted
}
// More custom tag categories
]
Creating a tag category
Creates a new category for organising tags. Specify which record types (CVs, references, customers) can use tags from this category. The category can also carry an external unique ID that links it to an external system.
Creating a category needs the internationalmanager role or higher. Keys with a lower role, such as external or consultant, get a 403.
Request
POST https://<subdomain>.flowcase.com/api/v1/masterdata/custom_tags/custom_tag_category
Request body
Wrap the fields in a masterdata key. The values key is required, even when empty. Every other field is optional.
{
"masterdata": {
"values": { "int": "NAME", "no": "NAME" },
"external_unique_id": "EXTERNAL_UNIQUE_ID", // optional
"can_be_used_for_cvs": true, // optional
"can_be_used_for_references": true, // optional
"can_be_used_for_customers": true, // optional
"allow_filtering": false, // optional
"lock_for_integrations": false // optional
}
}
Response
A successful create returns 200, not 201. The new category comes back with an empty custom_tags array.
{
"id": "CUSTOM_TAG_CATEGORY_ID_1",
"values": { "int": "NAME", "no": "NAME" },
"external_unique_id": "EXTERNAL_UNIQUE_ID",
"can_be_used_for_cvs": true,
"can_be_used_for_references": true,
"can_be_used_for_customers": true,
"custom_tags": []
}
A missing or malformed masterdata wrapper returns 400. An external_unique_id already used by another category returns 422.
Updating a tag category
Changes an existing category. You can update the name translations, the external ID and the usage flags.
Request
PUT https://<subdomain>.flowcase.com/api/v1/masterdata/custom_tags/custom_tag_category/<custom_tag_category_id>
Request body
{
"masterdata": {
"values": { "int": "NAME", "no": "NAME" }, // optional
"external_unique_id": "EXTERNAL_UNIQUE_ID", // optional
"can_be_used_for_cvs": true, // optional
"can_be_used_for_references": true, // optional
"can_be_used_for_customers": true // optional
}
}
Response
The updated record is returned.
{
"id": "CUSTOM_TAG_CATEGORY_ID_1",
"values": { "int": "NAME", "no": "NAME" },
"external_unique_id": "EXTERNAL_UNIQUE_ID",
"can_be_used_for_cvs": true,
"can_be_used_for_references": true,
"can_be_used_for_customers": true,
"custom_tags": []
}
Deleting a tag category
Permanently removes a tag category.
This also deletes every tag in the category, and removes the associations between those tags and any records (CVs, customers, reference projects). It cannot be undone.
Deleting a category needs the internationalmanager role.
Request
DELETE https://<subdomain>.flowcase.com/api/v1/masterdata/custom_tags/custom_tag_category/<custom_tag_category_id>
Response
The response is 204 No Content with an empty body. A category ID that does not exist, has already been deleted, or is malformed returns 500.
Listing custom tags
Retrieves tags in a category, page by page. The query parameter finds tags by name in any supported language.
The query filter is a useful way to check whether a tag with a given value already exists in the category, so you do not create a duplicate.
Request
GET https://<subdomain>.flowcase.com/api/v1/masterdata/custom_tags/custom_tag?offset=0&limit=100&category_ids=<custom_tag_category_id>
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
category_ids |
string | required | ID of the tag category to list tags from. Despite the plural name, only a single category ID is accepted. |
offset |
integer | optional | Number of items to skip before returning results. Default 0. |
limit |
integer | optional | Maximum number of items to return. Default and maximum is 100 per page. A limit above 100 returns 400 Bad Request. |
query |
string | optional | Case-insensitive substring match on tag values. For example, query=full matches Full time employee. |
language_code |
string | optional | Which language variant to match query against, for example int or no. Also sets the sort order. If omitted, query searches every language variant. |
use_legacy_codes |
string | optional | Language code format in values. Default true, which returns legacy codes such as int, se and cn. Set to false for ISO 639-1 codes such as en, sv and zh. |
Omitting category_ids, or passing an ID that does not exist, returns an empty array rather than an error, so send it on every request.
When using the query parameter:
- Without
language_code: searches every language value.query=Managerfinds tags containing "Manager" in any language. - With
language_code: searches only the given language.query=Manager&language_code=intfinds only tags whose international (English) value contains "Manager".
Response
The response is a bare JSON array with no pagination envelope and no total count. Detect the end of the results by receiving fewer items than limit. An empty array is returned when nothing matches.
[
{
"id": "CUSTOM_TAG_ID",
"values": { "int": "NAME", "no": "NAME" },
"external_unique_id": "EXTERNAL_UNIQUE_ID",
"custom_tag_category_id": "CUSTOM_TAG_CATEGORY_ID"
// Some fields omitted
}
// More custom tags for category
]
A tag has these fields:
| Field | Description |
|---|---|
id |
Unique identifier for the tag. |
values |
The tag label per language code. |
external_unique_id |
Optional identifier linking the tag to an external system. null or an empty string when not set. |
custom_tag_category_id |
ID of the category the tag belongs to. |
category_ids |
Array holding the parent category ID. Always a single element, since a tag has exactly one category. |
Creating a custom tag
Adds a new tag to a category. Give the tag at least one language value, and assign it to exactly one category. Use the external ID to link the tag to its source system.
Creating a tag needs the internationalmanager role or higher. Keys with a lower role, such as external or consultant, get a 403.
Request
POST https://<subdomain>.flowcase.com/api/v1/masterdata/custom_tags/custom_tag
Request body
Wrap the fields in a masterdata key. category_ids is required and holds the ID of the target category.
{
"masterdata": {
"values": { "int": "NAME", "no": "NAME" },
"external_unique_id": "EXTERNAL_UNIQUE_ID", // optional
"category_ids": ["CUSTOM_TAG_CATEGORY_ID"]
}
}
Response
A successful create returns 200, not 201. The response is the created tag with its generated ID.
{
"id": "CUSTOM_TAG_ID",
"values": { "int": "NAME", "no": "NAME" },
"external_unique_id": "EXTERNAL_UNIQUE_ID",
"custom_tag_category_id": "CUSTOM_TAG_CATEGORY_ID_1"
// Some fields omitted
}
A missing category_ids, an empty category_ids array or a category ID that does not exist returns 400. An external_unique_id already used by another tag returns 422. A body sent without the masterdata wrapper returns 500.
Updating a custom tag
Changes an existing tag. You can update the translations and the external ID.
Request
PUT https://<subdomain>.flowcase.com/api/v1/masterdata/custom_tags/custom_tag/<custom_tag_id>
Request body
{
"masterdata": {
"values": { "int": "NAME", "no": "NAME" }, // optional
"external_unique_id": "EXTERNAL_UNIQUE_ID", // optional
"custom_tag_category_id": "CUSTOM_TAG_CATEGORY_ID_1"
}
}
Response
The updated record is returned.
{
"id": "CUSTOM_TAG_ID",
"values": { "int": "NAME", "no": "NAME" },
"external_unique_id": "EXTERNAL_UNIQUE_ID",
"custom_tag_category_id": "CUSTOM_TAG_CATEGORY_ID_1"
// Some fields omitted
}
Deleting a custom tag
Removes a tag from the account. This also removes every association between the tag and any records (CVs, customers, reference projects). It cannot be undone.
The category_ids query parameter is required and must name the category the tag belongs to. Despite the plural name, only a single category ID is accepted.
Deleting a tag needs the internationalmanager role.
Request
DELETE https://<subdomain>.flowcase.com/api/v1/masterdata/custom_tags/custom_tag/<custom_tag_id>?category_ids=<custom_tag_category_id>
Response
The response is 204 No Content.
A missing category_ids, or one naming a category that does not exist, returns 400. The call is not idempotent: deleting a tag that is already gone returns 404, as does a tag that belongs to a different category from the one you sent.
Bulk deleting custom tags
Removes several tags from a category in one request. This is quicker than deleting tags one at a time when you have many to remove. Every association between the deleted tags and any records (CVs, customers, reference projects) is removed too. It cannot be undone.
Request
DELETE https://<subdomain>.flowcase.com/api/v1/masterdata/custom_tags/custom_tag_category/<custom_tag_category_id>/bulk_delete?tag_ids[]=<CUSTOM_TAG_ID_1>&tag_ids[]=<CUSTOM_TAG_ID_2>&tag_ids[]=<CUSTOM_TAG_ID_3>
The tag_ids parameter takes several tag IDs as query parameters. At least one tag ID must be given, and every ID must belong to the category in the path.
Response
The response is 204 No Content.
Errors
- 400 Bad Request: returned when
tag_idsis empty, or when the category ID is invalid.
Tags on CVs (résumés)
For a master CV the tag is held against the user rather than the CV itself. For a tailored CV in a proposal, the tag is held against that CV.
Adding and removing tags needs write permission on the CV. If the tag's category has lock_for_integrations: true, only API users and users with the internationalmanager role can change tags from that category.
Adding a custom tag to a CV
Attaches a tag to a CV. A CV can hold several tags from the same category. For the tag to appear in the CV's custom_tags array, its category needs can_be_used_for_cvs: true, although the API does not enforce this when you write. A tag from any category can be added, but only qualifying tags come back in the response.
Request
POST https://<subdomain>.flowcase.com/api/v3/cvs/<user_id>/<cv_id>/custom_tags
Request body
{
"custom_tag_category_id": "CUSTOM_TAG_CATEGORY_ID",
"custom_tag_id": "CUSTOM_TAG_ID"
}
Response
The response is the updated CV. The call is idempotent: adding a tag that is already on the CV returns the same response, with no error and no duplicate.
A CV ID, category ID or tag ID that does not exist returns 404, as does a request missing a required body field.
Removing a custom tag from a CV
Removes the link between a tag and a CV. The tag itself stays in the account and can still be used elsewhere.
Request
DELETE https://<subdomain>.flowcase.com/api/v3/cvs/<user_id>/<cv_id>/custom_tags/<custom_tag_id>
Response
The response is 204 No Content. The call is not idempotent: removing a tag that is not on the CV returns 404.
Listing custom tags on a CV
To see the tags on a CV, fetch the whole CV and read its custom tag fields.
Request
GET https://<subdomain>.flowcase.com/api/v3/cvs/<user_id>/<cv_id>
Response
{
"_id": "CV_ID",
"bruker_id": "USER_ID",
// Other CV sections and fields omitted
"custom_tag_ids": [
"CUSTOM_TAG_ID_1",
"CUSTOM_TAG_ID_2"
// More custom tag IDs
]
}
The CV also holds a custom_tags array with the full tag objects and their category embedded. Both fields only include tags whose category has can_be_used_for_cvs: true. See CVs & Résumés for the rest of the CV response, and Search for CVs for searching CVs by tag.
Tags on customers
Tags applied to a customer come back in the custom_tags array of the customer object. See Customers for the rest of the customer response.
Adding a custom tag to a customer
Attaches a tag to a customer record. The tag's category needs can_be_used_for_customers: true. Use this to categorise and search for customers by their attributes.
Request
POST https://<subdomain>.flowcase.com/api/v2/company/cv/customers/<customer_id>/custom_tags
Request body
{
"custom_tag_category_id": "CUSTOM_TAG_CATEGORY_ID",
"custom_tag_id": "CUSTOM_TAG_ID"
}
Response
The response is the updated customer.
Removing a custom tag from a customer
Removes the link between a tag and a customer. The tag itself stays in the account and can still be used with other customers.
Request
DELETE https://<subdomain>.flowcase.com/api/v2/company/cv/customers/<customer_id>/custom_tags/<custom_tag_id>
Response
The response is 204 No Content.
Tags on reference projects
Adding and removing tags needs write permission on the reference project. If the tag's category has lock_for_integrations: true, only API users and users with the internationalmanager role can change tags from that category.
Adding a custom tag to a project
Attaches a tag to a reference project. Use this to categorise projects by type, technology, industry and so on. For the tag to appear in the project's custom_tags array, its category needs can_be_used_for_references: true, although the API does not enforce this when you write. A tag from any category can be added, but only qualifying tags come back in the response.
Request
POST https://<subdomain>.flowcase.com/api/v2/company/cv/customers/<customer_id>/projects/<project_id>/custom_tags
Request body
{
"custom_tag_category_id": "CUSTOM_TAG_CATEGORY_ID",
"custom_tag_id": "CUSTOM_TAG_ID"
}
Response
The response is the full updated project, including all of its sections.
Unlike the CV endpoint, this call is not idempotent: adding a tag that is already on the project returns 422 Unprocessable Entity with details: ["Custom tag må være unik"]. A customer ID, project ID, category ID or tag ID that does not exist returns 404, as does a request missing a required body field.
Removing a custom tag from a project
Removes the link between a tag and a project. Only that project-tag link goes; the tag stays available for other projects.
The custom_tag_id is the id of an entry in the project's custom_tags array.
Request
DELETE https://<subdomain>.flowcase.com/api/v2/company/cv/customers/<customer_id>/projects/<project_id>/custom_tags/<custom_tag_id>
Response
The response is 204 No Content. The call is not idempotent: removing a tag that is not on the project returns 404.
Tags on users
Tags on users are not set through a dedicated endpoint. Pass ensure_unique_custom_tag_ids_by_category when you create or update a user, which sets one tag per category and removes any earlier tag in that category. See Custom tags in the user synchronisation guide.
Errors
| Status | Cause |
|---|---|
| 400 | Bad request, for example a limit above 100 when listing tags, a missing category_ids when deleting a tag, empty tag_ids on bulk delete, or a missing masterdata wrapper when creating a category. |
| 401 | Missing or invalid authentication. |
| 403 | The API key is invalid or disabled, or the user lacks the role the operation needs. |
| 404 | The tag, category, CV, customer or project does not exist, or the tag is not attached to the record. |
| 422 | Validation failed, for example a duplicate external_unique_id, or a tag already attached to a reference project. |
| 429 | Rate limit exceeded. See Rate Limits. |
| 500 | Returned when deleting a category whose ID is unknown, and when creating a tag without the masterdata wrapper. |
See Errors & Response Codes for the full list of status codes the API returns.
What's next
- See the Integrations API reference for the full custom tag schemas and per-operation details.
- See Masterdata for the other Masterdata types you can manage through the API.
- See Managing References for the wider customer and reference project sync workflow.
- See Customers and Users for the records tags are attached to.