Unique ID Field
Auto-generate sequential identifiers on records — ticket numbers, order IDs, invoice numbers — with the UNIQUE_ID custom field type.
A Unique ID field assigns each record a sequential number — the basis for ticket numbers, order IDs, invoice numbers, or any per-workspace counter. It maps to the UNIQUE_ID value of the CustomFieldType enum.
Records are Record objects and workspaces are Workspace objects in the API. A Unique ID field runs in one of two modes: sequence mode (useSequenceUniqueId: true) auto-numbers records in creation order, or manual mode (the default) behaves like a text field you fill in yourself.
Overview
In sequence mode, Blue maintains a counter per field and assigns the next integer to each record. The raw counter value is stored as an integer; the prefix and sequenceDigits you configure are applied at display time in the app, so the API returns the bare sequence number (42), not the formatted string (TASK-042). Assignment runs asynchronously in a background worker that holds a row lock while it numbers records, so concurrent record creation never produces duplicates or gaps from races.
Create
Create a sequence-mode field with the createCustomField mutation. The field is scoped to the workspace in the blue-workspace-id header — there is no projectId argument.
mutation CreateUniqueIdField {
createCustomField(input: { name: "Ticket Number", type: UNIQUE_ID, useSequenceUniqueId: true }) {
id
name
type
useSequenceUniqueId
}
}To format the displayed value, add a prefix and zero-pad with sequenceDigits, and optionally start the counter at a specific number with sequenceStartingNumber:
mutation CreateFormattedUniqueIdField {
createCustomField(
input: {
name: "Order ID"
type: UNIQUE_ID
description: "Auto-generated order identifier"
useSequenceUniqueId: true
prefix: "ORD-"
sequenceDigits: 4
sequenceStartingNumber: 1000
}
) {
id
name
type
useSequenceUniqueId
prefix
sequenceDigits
sequenceStartingNumber
}
}CreateCustomFieldInput (UNIQUE_ID)
| Parameter | Type | Required | Description |
|---|---|---|---|
name | String! | Yes | Display name of the field. |
type | CustomFieldType! | Yes | Must be UNIQUE_ID. |
description | String | No | Help text shown on the field. |
useSequenceUniqueId | Boolean | No | Enable auto-numbering. Omit or false for manual mode. |
prefix | String | No | Text prepended to the displayed value (e.g. ORD-). Display-only. |
sequenceDigits | Int | No | Zero-pad the displayed number to this width (e.g. 4 → 0042). Display-only. |
sequenceStartingNumber | Int | No | First number in the sequence. Defaults to 1. Applies only to the first assignment. |
sequenceScope | SequenceScope | No | PROJECT for one workspace series, or FIELD to restart per scope-field value. |
sequenceScopeFieldId | String | No | Scope field ID when sequenceScope is FIELD. |
enableBulkAction | Boolean | No | Allow this field in bulk actions. Not all field types support bulk actions; UNIQUE_ID does. |
Response
{
"data": {
"createCustomField": {
"id": "clm4n8qwx000008l0g4oxdqn7",
"name": "Order ID",
"type": "UNIQUE_ID",
"useSequenceUniqueId": true,
"prefix": "ORD-",
"sequenceDigits": 4,
"sequenceStartingNumber": 1000
}
}
}When the field is created in sequence mode, a background job numbers every existing record in the workspace and continues numbering new records as they are created.
Restart numbering per field value
Set sequenceScope: FIELD and sequenceScopeFieldId to restart numbering for each scope value. The scope field must be in the same workspace. Supported fields are single Reference, Referenced by, single Select, and single Assignee fields.
A Referenced by scope assigns a number only when it currently contains exactly one record. Empty or multi-record results do not identify one group and remain unnumbered.
Set a value
In sequence mode you do not set the value — Blue assigns it automatically. The four lines below apply only to manual mode (useSequenceUniqueId omitted or false), where the field behaves like a text field. Write a value with setRecordCustomField using the text parameter.
mutation SetUniqueIdValue {
setRecordCustomField(
input: { todoId: "todo_123", customFieldId: "field_123", text: "CUSTOM-ID-001" }
)
}setRecordCustomField returns a Boolean! — there are no subfields to select. Read the value back with a separate query (see below).
{
"data": {
"setRecordCustomField": true
}
}SetRecordCustomFieldInput (UNIQUE_ID, manual mode)
| Parameter | Type | Required | Description |
|---|---|---|---|
todoId | String! | Yes | The record to set the value on. |
customFieldId | String! | Yes | The Unique ID field. |
text | String | No | The manual identifier to store. |
Read a value
Read records and their field values with the todos query under recordQueries. TodosFilter.companyIds is required; scope further with projectIds. The query returns a TodosResult (items + pageInfo), and Record.customFields is a list of CustomField objects — there is no wrapper type.
query GetRecordsWithUniqueIds {
recordQueries {
todos(filter: { companyIds: ["company_123"], projectIds: ["project_123"] }) {
items {
id
title
customFields {
name
type
prefix
sequenceDigits
sequenceId
text
value
}
}
pageInfo {
totalItems
hasNextPage
}
}
}
}On each CustomField element:
- Sequence mode:
sequenceId(andvalue) hold the raw integer counter.prefix/sequenceDigitscome back as the field’s display config — apply them yourself to renderORD-0042.textisnull. - Manual mode:
textholds the value you set;sequenceIdandvaluearenull.
{
"data": {
"recordQueries": {
"todos": {
"items": [
{
"id": "clm4n8qwx000008l0g4oxdqn7",
"title": "Fix login issue",
"customFields": [
{
"name": "Order ID",
"type": "UNIQUE_ID",
"prefix": "ORD-",
"sequenceDigits": 4,
"sequenceId": 42,
"text": null,
"value": 42
}
]
}
],
"pageInfo": { "totalItems": 1, "hasNextPage": false }
}
}
}
}Returns (CustomField, UNIQUE_ID)
| Field | Type | Description |
|---|---|---|
useSequenceUniqueId | Boolean | Whether auto-numbering is enabled. |
prefix | String | Display prefix for generated values. |
sequenceDigits | Int | Display zero-padding width. |
sequenceStartingNumber | Int | The configured starting number. |
sequenceId | Int | The raw sequence number assigned to this record (sequence mode). |
text | String | The stored value in manual mode; null in sequence mode. |
value | JSON | The record value — the integer sequence number for UNIQUE_ID. |
Notes
- The API returns the bare number, not the formatted string.
prefixandsequenceDigitsare display config; combine them client-side (`${prefix}${String(sequenceId).padStart(sequenceDigits, '0')}`) to reproduce what the app shows. - Assignment is asynchronous. New records get a number shortly after creation, not in the same transaction. Don’t assume
sequenceIdis populated the instant a record is created. - Sequences never reuse numbers. Deleting a record leaves a gap; the counter only moves forward.
sequenceStartingNumbersets the first value only — once the counter advances, later edits to it don’t renumber existing records. - Sequences are per field. Each
UNIQUE_IDfield keeps its own counter, scoped to its workspace. enableBulkActionis an optionalCreateCustomFieldInputflag that exposes a field in bulk actions;UNIQUE_IDsupports it.
Permissions
Creating or editing a Unique ID field requires the OWNER or ADMIN role on the workspace. Setting a manual value and reading values use standard record edit and view permissions.
Errors
| Code | When |
|---|---|
FORBIDDEN | The caller lacks OWNER/ADMIN on the workspace, or edit access to the record. |
CUSTOM_FIELD_NOT_FOUND | The customFieldId does not exist in this workspace. |
TODO_NOT_FOUND | The todoId in setRecordCustomField does not exist. |
BAD_USER_INPUT | The input is malformed (e.g. enableBulkAction on an unsupported type). |