Project Custom Metadata API
The Project Custom Fields API lets you define structured metadata tailored to your workflows. Create fields once, and they appear everywhere within your project's scope.
Note: This API is part of the Metadata API. It requires an active Egnyte account with the Projects feature enabled and customized project metadata enabled for your domain.
Base URL
https://{domain}.egnyte.com/pubapi/v1/properties/project-tag/custom-fields
Authentication
All requests require an OAuth 2.0 Bearer token in the Authorization header:
Authorization: Bearer {access_token}
See Authentication for details on obtaining a token.
Key Capabilities
- Define custom metadata fields with multiple data types:
string,integer,decimal,date,enum(dropdown with single select),multi_value_enum(dropdown with multi select),labels. - Manage lifecycle via create, update, and delete operations.
Prerequisites
- Active Egnyte account with the Projects feature enabled.
- Customized project metadata must be enabled for your domain.
- API access token with the required scopes.
Common HTTP Headers
| Header | Description | Value |
|---|---|---|
Content-Type | Specifies the format of the request body | application/json |
Authorization | OAuth token obtained through the OAuth flow | Bearer {OAuth token} |
X-Egnyte-Force-Delete | Set to Yes to force delete a custom field that is in use | Yes |
Endpoints Summary
| Method | Endpoint | Description |
|---|---|---|
GET | /pubapi/v1/properties/project-tag/custom-fields | List all custom field definitions |
POST | /pubapi/v1/properties/project-tag/custom-fields | Create a custom field definition |
PATCH | /pubapi/v1/properties/project-tag/custom-fields/{field_name} | Update a custom field definition |
PATCH | /pubapi/v1/properties/project-tag/custom-fields/{field_name}/data | Delete custom field definition data set |
DELETE | /pubapi/v1/properties/project-tag/custom-fields/{field_name} | Delete a custom field definition |
List All Custom Field Definitions
Fetch all project custom field definitions for the domain.
Request
GET /pubapi/v1/properties/project-tag/custom-fields
Example Request
curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/properties/project-tag/custom-fields" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response
200 OK
Returns a keys object — a dictionary of custom field definitions keyed by field name.
| Field | Type | Description |
|---|---|---|
keys | object | Dictionary of custom field definitions, keyed by field name |
keys.{name} | object | Individual custom field definition |
name | string | Unique internal identifier for the field |
displayName | string | User-friendly display name (max 40 characters) |
type | string | Field data type (see Data Types) |
data | array<string> | Predefined values for enum, labels, and multi_value_enum types |
helpText | string | Help text (max 200 characters) |
priority | integer | Display order (0–65535, lower values appear first) |
createdAt | string | Custom field creation timestamp (ISO 8601) |
updatedAt | string | Custom field last updated timestamp (ISO 8601) |
timezoneIndependent | boolean | Only present on date-type fields. When true, values must be UTC midnight milliseconds. |
Example Response
{
"keys": {
"budget_code": {
"name": "budget_code",
"displayName": "Budget Code",
"type": "string",
"helpText": "Enter the project budget code",
"priority": 100,
"createdAt": "2026-03-10T10:30:00Z",
"updatedAt": "2026-03-10T10:30:00Z"
},
"project_category": {
"name": "project_category",
"displayName": "Project Category",
"type": "enum",
"data": ["Infrastructure", "Development", "Research", "Operations"],
"helpText": "Select the project category",
"priority": 150,
"createdAt": "2026-03-10T10:35:00Z",
"updatedAt": "2026-03-10T10:35:00Z"
},
"project_tags": {
"name": "project_tags",
"displayName": "Project Tags",
"type": "labels",
"data": ["high-priority", "customer-facing", "internal"],
"helpText": "Add relevant tags for this project",
"priority": 200,
"createdAt": "2026-03-10T10:40:00Z",
"updatedAt": "2026-03-10T11:20:00Z"
},
"start_date": {
"name": "start_date",
"displayName": "Start Date",
"type": "date",
"helpText": "Project start date",
"priority": 300,
"timezoneIndependent": true,
"createdAt": "2026-03-10T10:45:00Z",
"updatedAt": "2026-03-10T10:45:00Z"
}
}
}
HTTP Status Codes
| Status | Description |
|---|---|
| 200 OK | Successful operation |
| 403 Forbidden | User is not authorized or feature is disabled |
Create a Custom Field Definition
Create a new project custom field definition.
Request
POST /pubapi/v1/properties/project-tag/custom-fields
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
displayName | string | Yes | Display name (max 40 characters). The internal name key is auto-derived (lowercase, spaces → hyphens). |
type | string | Yes | Data type. Allowed values: string, integer, decimal, date, enum, labels, multi_value_enum |
data | array<string> | Conditional | Required for enum and multi_value_enum. Optional for labels. Must not be provided for primitive types. |
helpText | string | Yes | Custom field description. Must be between 20 and 200 characters. |
priority | integer | No | Display order in project settings (0–65535). Omitting appends the field last. |
timezoneIndependent | boolean | No | Only applies to date-type fields. When true, values must be UTC midnight milliseconds. Defaults to false (timezone-dependent) when omitted. Set to true to opt in to timezone-independent behavior. Cannot be reverted to false once set. |
Note: The helpText field is mandatory for new custom fields and must be between 20 and 200 characters.
Validation Rules
- Dropdown with Single Select & Dropdown with Multi Select: Provide a non-empty
dataarray. - Labels: Provide a non-empty
dataarray — optional but recommended. - Primitive types: Do not include
dataforstring,integer,decimal,date. - Reserved field:
project_statusis a reserved field. New custom status values can be added to it, but itsdisplayName,helpText,priority, and default status cannot be modified. - Name generation: Derived from
displayName— lowercase, spaces become hyphens. Must be unique per domain. - Duplicate names: Auto-resolved with numeric suffixes (e.g.,
field-1,field-2). - Max limit: Respect the domain's maximum custom fields limit.
Example Request — Create a Labels Field
curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/properties/project-tag/custom-fields" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -d '{ "displayName": "Project Tags", "type": "labels", "data": [ "infrastructure", "customer-facing", "internal" ], "helpText": "Add relevant tags (you can add custom values)", "priority": 200 }'
Example Request — Create a Multi-Select Dropdown
curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/properties/project-tag/custom-fields" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -d '{ "displayName": "Project Tags", "type": "multi_value_enum", "data": [ "infrastructure", "customer-facing", "internal" ], "helpText": "Add relevant tags (you can add custom values)", "priority": 200 }'
Response
HTTP Status Codes
| Status | Description |
|---|---|
| 201 Created | Custom field created successfully (empty body) |
| 400 Bad Request | Validation error — see Error Codes Reference |
| 403 Forbidden | Feature is disabled or unauthorized |
Update a Custom Field Definition
Update an existing custom field definition.
Request
PATCH /pubapi/v1/properties/project-tag/custom-fields/{field_name}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
field_name | string | Yes | The unique internal name of the custom field to update |
Request Body
All fields are optional.
| Parameter | Type | Required | Description |
|---|---|---|---|
displayName | string | No | New display name (max 40 characters) |
helpText | string | No | Updated field description. If provided, must be between 20 and 200 characters. |
priority | integer | No | New display order (0–65535). Omitting leaves existing order unchanged. |
data | array<string> | Conditional | Required for enum, labels, and multi_value_enum types. Dropdown with single select (enum): New values replace existing values. Dropdown with multi select (multi_value_enum) and labels: New values are appended to existing values. |
timezoneIndependent | boolean | No | Only applies to date-type fields. Once set to true, cannot be changed back to false. |
Note: If helpText is provided, it must be between 20 and 200 characters.
Example Request
curl -i -X PATCH "https://{domain}.egnyte.com/pubapi/v1/properties/project-tag/custom-fields/{field_name}" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -d '{ "displayName": "Project Tags (Updated)", "data": [ "architecture" ], "helpText": "Updated help text for project tags", "priority": 150 }'
Response
HTTP Status Codes
| Status | Description |
|---|---|
| 204 No Content | Update successful (empty body) |
| 400 Bad Request | Validation error — see Error Codes Reference |
| 404 Not Found | Custom field does not exist |
Delete Custom Field Definition Data
Remove specific data values from an enum, labels, or multi_value_enum field, and remove their usage from all existing projects.
Warning: This operation cannot be undone. When the field data is in use, a 403 error is returned. To force deletion, set the X-Egnyte-Force-Delete header to Yes.
Request
PATCH /pubapi/v1/properties/project-tag/custom-fields/{field_name}/data
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
field_name | string | Yes | The unique name of the custom field whose data to delete |
Request Body
A JSON array of string values to delete:
[
"infrastructure",
"customer-facing",
"internal"
]
Example Request
curl -i -X PATCH "https://{domain}.egnyte.com/pubapi/v1/properties/project-tag/custom-fields/{field_name}/data" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -d '[ "infrastructure", "customer-facing", "internal" ]'
Response
HTTP Status Codes
| Status | Description |
|---|---|
| 204 No Content | Data deleted successfully (empty body) |
| 403 Forbidden | Field data is in use. Set X-Egnyte-Force-Delete: Yes to override. |
| 404 Not Found | Custom field does not exist |
Delete a Custom Field Definition
Delete a custom field definition and remove all its values from all existing projects.
Warning: This operation cannot be undone. When the field is in use, a 403 error is returned. To force deletion, set the X-Egnyte-Force-Delete header to Yes.
Request
DELETE /pubapi/v1/properties/project-tag/custom-fields/{field_name}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
field_name | string | Yes | The unique name of the custom field to delete |
Example Request
curl -i -X DELETE "https://{domain}.egnyte.com/pubapi/v1/properties/project-tag/custom-fields/{field_name}" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response
HTTP Status Codes
| Status | Description |
|---|---|
| 204 No Content | Field deleted successfully (empty body) |
| 403 Forbidden | Field is in use. Set X-Egnyte-Force-Delete: Yes to override. |
| 404 Not Found | Custom field does not exist |
Timezone-Independent Date Fields
date-type custom fields support a timezoneIndependent flag.
timezoneIndependent value | Behavior |
|---|---|
true | Values must be epoch milliseconds at exactly UTC midnight (divisible by 86400000). The date is displayed as-is, without timezone adjustment. |
false | Values are stored and displayed in the user's local timezone (legacy behavior). |
Default: New date fields created via the Public API default to timezoneIndependent: false (timezone-dependent). To opt in to timezone-independent behavior, explicitly set timezoneIndependent: true.
Irreversible: Once a field is set to timezoneIndependent: true, it cannot be changed back to false.
Data Types
Supported field types for custom field definitions:
| Type | Description | Requires data | Example Usage |
|---|---|---|---|
string | Single-line text input | No | Budget codes, project IDs, names |
integer | Whole numeric value | No | Team size, duration |
decimal | Decimal numeric value | No | Budget amounts |
date | Date value. When timezoneIndependent is true, stored as UTC midnight epoch milliseconds (see Timezone-Independent Date Fields). | No | Start date, deadline, milestone |
enum | Dropdown with single select | Yes | Priority, status, category |
labels | Multi-value free-text field | No | Tags, labels, keywords |
multi_value_enum | Dropdown with multi select | Yes | Project departments |
Error Codes
Errors follow a standard response format:
{
"errorMessage": "Human-readable error description",
"errorCode": "MACHINE_READABLE_CODE"
}
| Status | Error | Description | Resolution |
|---|---|---|---|
| 400 | EMPTY_KEY_DATA | enum or multi_value_enum field is missing the required data array | Provide a non-empty data array for enum and multi_value_enum types |
| 400 | UNWANTED_KEY_DATA | Primitive type field has an unexpected data array | Remove data from requests for string, integer, decimal, and date types |
| 400 | MISSING_KEYS_TO_UPDATE | The specified field name does not exist | Verify the field_name using the List endpoint before updating |
| 400 | MAX_PROJECT_CUSTOM_FIELDS_REACHED | The domain's maximum custom fields limit has been exceeded | Delete unused fields before creating new ones |
| 400 | TIMEZONE_INDEPENDENT_FEATURE_DISABLED | timezoneIndependent: true was sent but the feature is not enabled for this domain | Contact Egnyte Support to enable this feature for your domain |
| 400 | TIMEZONE_INDEPENDENT_DOWNGRADE_NOT_ALLOWED | A date field with timezoneIndependent: true cannot be changed to false | The timezoneIndependent flag is irreversible once set to true |
| 400 | Bad Request | Date value is not a valid timezone-independent date | For timezoneIndependent: true DATE fields, the value must be epoch milliseconds at exactly UTC midnight (divisible by 86400000) |
| 400 | DUPLICATE_STATUS_VALUES | project_status field contains duplicate values | Ensure all values in the project_status data array are unique |
| 403 | FEATURE_DISABLED | Custom project metadata is disabled for this domain | Contact your Egnyte administrator to enable the feature |
| 404 | NOT_FOUND | The custom field does not exist | Verify the field_name is correct using the List endpoint |
| 500 | INTERNAL_SERVER_ERROR | The API encountered an unexpected error | Retry the request; contact Egnyte Support if the issue persists |
Related Resources
- Authentication — How to obtain and refresh OAuth tokens
- Metadata API — Manage custom metadata on files and folders
- Project Folder API — Manage project folders and metadata
