Skip to main content
HoundDog API Documentation

Custom fields

Custom fields are the extra fields your account adds to its records, such as a region or an account manager. These routes list, create, change, archive and restore the definitions: each field's id (the key of a record's custom_fields map), its name, its type and where it appears. The dashboard's Settings > Custom Fields manages the same fields under the same rules. Every route on this page needs custom fields enabled on the account (enable_custom_fields); otherwise it answers 403 feature_disabled.

Operation Scope
GET /custom_fields read
GET /custom_fields/:id read
POST /custom_fields read_write
PATCH /custom_fields/:id read_write
POST /custom_fields/:id/archive read_write
POST /custom_fields/:id/unarchive read_write

Fields are archived, never deleted, through the API: there is no DELETE route. An archived field keeps its values and can be restored.

The custom field entity

{
  "id": 12,
  "name": "Region",
  "field_type": "string",
  "applies_to": ["parties"],
  "show_on_triage_queue": false,
  "archived": false,
  "created_at": "2026-05-02T09:00:00Z",
  "updated_at": "2026-09-30T09:00:00Z"
}
  • field_type is the field's type, one of the API names in Field types.
  • applies_to lists where the field appears: parties for a field on parties, or an empty list.
  • A field on projects lists projects too: parties, projects, or both (in that order).
  • show_on_triage_queue is true when the field is shown on the triage queue in the dashboard.
  • archived is true for an archived field. An archived field is not served in any record's custom_fields, and a write naming it is 422 validation_failed naming custom_fields. Its values are kept, and come back if the field is restored.
  • A field type that has settings of its own (for example, a list of choices) adds them as new members of this entity. Existing members never change meaning.

Field types

Type API name Settings of its own
String string None.
Integer integer None.
User user None.

What each type serves in a record's custom_fields entry, what a write takes and which values it accepts are in Custom field types on the Parties page.

GET /custom_fields

The account's active custom fields in the collection envelope (see Pagination), ordered by id.

Filters:

  • applies_to: parties, only the fields that appear on parties.
  • applies_to=projects lists only the fields that appear on projects.
  • include_archived: true also lists archived fields. By default only active fields are listed.

GET /custom_fields/:id

One field, archived or not. A field id of another account is 404 not_found.

Rules

The dashboard and the API apply the same rules:

  • Names are unique among your account's active fields, ignoring case and spaces around the name: Region, region and REGION are the same name. An archived field's name is free for a new field. A name already in use is 422 validation_failed naming name.
  • At most 50 active fields per account. Archived fields do not count. A create (or an unarchive) past 50 is 422 validation_failed with the message An account can have at most 50 active custom fields; archive one first.
  • A field's type is fixed once the field has a value on any record. Before that it can change. Changing it afterwards is 409 conflict with the message field_type cannot be changed once the field has values (to change the type, archive the field and create a new one; reuse its name only when nothing reads the field by name, see the next rule).
  • Fields are matched by id, but names matter too. Renaming or archiving a field changes nothing in a record's custom_fields keys. Spreadsheets, and your own code if it looks a field up by name, stop finding a field you rename or archive. Some HoundDog integrations and one-off tasks also read fields by name, and they treat an archived field differently: they keep reading and writing it, so values keep landing in a field that is hidden everywhere else. Never create a new field with the name of a field an integration reads, archived or not: the integration may then read either of the two. Check with whoever relies on a field before you rename or archive it, and before you reuse its name.

POST /custom_fields

Creates a field and answers 201 with the custom field entity. Accepts Idempotency-Key (see Idempotency keys): a repeat answers with the field the first request created.

{
  "name": "Crew size",
  "field_type": "integer",
  "applies_to": ["parties"],
  "show_on_triage_queue": false
}
  • name (required): the field's name, unique among your active fields (see Rules). Spaces around it are removed.
  • field_type (required): the type's API name, one of the names in Field types.
  • applies_to: where the field appears, ["parties"] when omitted. [] (or null) is allowed: the field appears nowhere until you change it. projects makes the field appear on projects as well. Adding projects on an account without projects is 403 feature_disabled naming applies_to.
  • show_on_triage_queue: show the field on the triage queue, false when omitted. Turning it on without the triage queue enabled is 403 feature_disabled naming show_on_triage_queue.

Errors: 400 validation_failed for a missing name or field_type, or a field_type or applies_to value that is not listed; 422 validation_failed for the name and the 50-field rules.

PATCH /custom_fields/:id

Changes a field (active or archived) and answers with the custom field entity. Only the members you send change; the entity a GET serves can be sent back as read, and changes nothing (no event is recorded either).

  • name, applies_to, show_on_triage_queue: as on the create. A name in use by another active field is 422 naming name. Removing parties (or projects) from applies_to hides the field's values on those records without deleting them; adding it back shows them again.
  • field_type: changes only while the field has no value on any record; otherwise 409 conflict (see Rules). Sending the type the field already has is not a change.
  • archived: accepted only with the value served. Use the archive and unarchive routes to change it; any other value is 422 naming archived.
  • id, created_at and updated_at are ignored.

POST /custom_fields/:id/archive

Archives the field and answers with the custom field entity (archived is true). An archived field:

  • is not served in any record's custom_fields, and a write naming it is 422 validation_failed naming custom_fields;
  • is hidden from the dashboard's forms, record pages, search, exports, spreadsheet imports and the triage queue;
  • keeps its values, which come back when it is restored;
  • if it is a User-type field, no longer assigns records to users ("Assigned to Me", the user's page and assignment notifications ignore it until it is restored).

Archiving does not move the updated_at of the records holding the field's values, so updated_since does not return them; follow it through the Custom Field Definition Archived event (see Events). Archiving an archived field changes nothing and answers 200. Accepts Idempotency-Key.

POST /custom_fields/:id/unarchive

Restores an archived field and answers with the custom field entity (archived is false); its values are served again. Refused with 422 validation_failed when an active field now has its name (naming name: rename one of them first) or when your account already has 50 active fields. Like archiving, it does not move the holders' updated_at (follow it through Custom Field Definition Restored). Unarchiving an active field changes nothing and answers 200. Accepts Idempotency-Key.

Events

Every change to a field definition, from the dashboard or the API, records an account event (see Events), and webhook subscriptions can subscribe to each type:

Type When
Custom Field Definition Created A field was created
Custom Field Definition Updated A field's name, type, applies_to or show_on_triage_queue changed; details.changes lists each with its old and new value
Custom Field Definition Archived, Custom Field Definition Restored A field was archived or restored
Custom Field Definition Deleted Support staff permanently deleted a field and its values (never through the API); details.values_removed is the number of values removed

A record's custom field value changing is a different event (see Events).