Repository: PagerDuty/go-pagerduty
Pull request #546 (2025-01-07 13:51:36)

[CSGINS-1452] Add support for Incident Type endpoints
<img width="265" alt="image" src="https://github.com/user-attachments/assets/d88fa2a2-f9e8-4f38-9d75-14efee362d94" />

https://developer.pagerduty.com/api-reference/d54514b5b003f-list-incident-workflows
https://developer.pagerduty.com/api-reference/1981087c1914c-create-an-incident-type
https://developer.pagerduty.com/api-reference/76f403c3fec76-get-an-incident-type
https://developer.pagerduty.com/api-reference/24faf357044f4-update-an-incident-type

https://developer.pagerduty.com/api-reference/37ca11e83a6e9-list-incident-type-custom-fields
https://developer.pagerduty.com/api-reference/423b6701f3f1b-create-a-custom-field-for-an-incident-type
https://developer.pagerduty.com/api-reference/9e96b7529c97f-get-an-incident-type-custom-field
https://developer.pagerduty.com/api-reference/16783ee8d81fe-update-a-custom-field-for-an-incident-type
https://developer.pagerduty.com/api-reference/71bf32f96ad05-delete-a-custom-field-for-an-incident-type

https://developer.pagerduty.com/api-reference/7473598460406-list-field-options-on-a-custom-field
https://developer.pagerduty.com/api-reference/ad9883b10b37a-create-a-field-option-for-a-custom-field
https://developer.pagerduty.com/api-reference/7ac20fa48535e-get-a-field-option-on-a-custom-field
https://developer.pagerduty.com/api-reference/bd33d66e0b2fd-update-a-field-option-for-a-custom-field
https://developer.pagerduty.com/api-reference/5c866a8ef0be2-delete-a-field-option-for-a-custom-field



Patch:
diff --git a/incident_type.go b/incident_type.go
new file mode 100644
index 0000000..4aca632
--- /dev/null
+++ b/incident_type.go
@@ -0,0 +1,358 @@
+package pagerduty
+
+import (
+	"context"
+
+	"github.com/google/go-querystring/query"
+)
+
+// IncidentType is allows to categorize incidents, such as a security incident, a major incident, or a fraud incident.
+type IncidentType struct {
+	Enabled     bool          `json:"enabled,omitempty"`
+	ID          string        `json:"id,omitempty"`
+	Name        string        `json:"name,omitempty"`
+	Parent      *APIReference `json:"parent,omitempty"`
+	Type        string        `json:"type,omitempty"`
+	Description string        `json:"description,omitempty"`
+	UpdatedAt   string        `json:"updated_at,omitempty"`
+	DisplayName string        `json:"display_name,omitempty"`
+}
+
+type incidentTypeResponse struct {
+	IncidentType IncidentType `json:"incident_type"`
+}
+
+// ListIncidentsTypesOptions is the structure used when passing parameters to the ListIncidentTypes API endpoint.
+type ListIncidentTypesOptions struct {
+	Filter string `url:"filter,omitempty"` // enabled disabled all
+}
+
+// ListIncidentsTypesResponse is the response structure when calling the ListIncidentTypes API endpoint.
+type ListIncidentTypesResponse struct {
+	IncidentTypes []IncidentType `json:"incident_types"`
+}
+
+// ListIncidentTypes list the available incident types.
+func (c *Client) ListIncidentTypes(ctx context.Context, o ListIncidentTypesOptions) (*ListIncidentTypesResponse, error) {
+	v, err := query.Values(o)
+	if err != nil {
+		return nil, err
+	}
+
+	resp, err := c.get(ctx, "/incidents/types?"+v.Encode(), nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result ListIncidentTypesResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result, err
+}
+
+// CreateIncidentTypeOptions contains the parameters for creating a new incident type.
+type CreateIncidentTypeOptions struct {
+	Name        string  `json:"name"`
+	DisplayName string  `json:"display_name"`
+	ParentType  string  `json:"parent_type"`
+	Enabled     *bool   `json:"enabled,omitempty"`
+	Description *string `json:"description,omitempty"`
+}
+
+// CreateIncidentType creates a new incident type.
+func (c *Client) CreateIncidentType(ctx context.Context, o CreateIncidentTypeOptions) (*IncidentType, error) {
+	d := map[string]CreateIncidentTypeOptions{
+		"incident_type": o,
+	}
+
+	resp, err := c.post(ctx, "/incidents/types", d, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result incidentTypeResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result.IncidentType, err
+}
+
+// GetIncidentTypeOptions contains the parameters for retrieving a specific incident type.
+type GetIncidentTypeOptions struct{}
+
+// GetIncidentType retrieves a specific incident type by ID or name.
+func (c *Client) GetIncidentType(ctx context.Context, idOrName string, o GetIncidentTypeOptions) (*IncidentType, error) {
+	resp, err := c.get(ctx, "/incidents/types/"+idOrName, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result incidentTypeResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result.IncidentType, err
+}
+
+// UpdateIncidentTypeOptions contains the parameters for updating an incident type.
+type UpdateIncidentTypeOptions struct {
+	DisplayName *string `json:"display_name,omitempty"`
+	Enabled     *bool   `json:"enabled,omitempty"`
+	Description *string `json:"description,omitempty"`
+}
+
+// UpdateIncidentType updates an existing incident type with the provided options.
+func (c *Client) UpdateIncidentType(ctx context.Context, idOrName string, o UpdateIncidentTypeOptions) (*IncidentType, error) {
+	d := map[string]UpdateIncidentTypeOptions{
+		"incident_type": o,
+	}
+
+	resp, err := c.put(ctx, "/incidents/types/"+idOrName, d, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result incidentTypeResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result.IncidentType, err
+}
+
+// IncidentTypeField represents a custom field configuration for an incident type.
+type IncidentTypeField struct {
+	Enabled      bool                      `json:"enabled,omitempty"`
+	ID           string                    `json:"id,omitempty"`
+	Name         string                    `json:"name,omitempty"`
+	Type         string                    `json:"type,omitempty"`
+	Self         string                    `json:"self,omitempty"`
+	Description  string                    `json:"description,omitempty"`
+	FieldType    string                    `json:"field_type,omitempty"` // single_value single_value_fixed multi_value multi_value_fixed
+	DataType     string                    `json:"data_type,omitempty"`  // boolean integer float string datetime url
+	CreatedAt    string                    `json:"created_at,omitempty"`
+	UpdatedAt    string                    `json:"updated_at,omitempty"`
+	DisplayName  string                    `json:"display_name,omitempty"`
+	DefaultValue interface{}               `json:"default_value,omitempty"`
+	IncidentType string                    `json:"incident_type,omitempty"`
+	Summary      string                    `json:"summary,omitempty"`
+	FieldOptions []IncidentTypeFieldOption `json:"field_options,omitempty"`
+}
+
+// IncidentTypeFieldOption represents an option for a custom field.
+type IncidentTypeFieldOption struct {
+	ID        string                       `json:"id,omitempty"`
+	Type      string                       `json:"type,omitempty"`
+	CreatedAt string                       `json:"created_at,omitempty"`
+	UpdatedAt string                       `json:"updated_at,omitempty"`
+	Data      *IncidentTypeFieldOptionData `json:"data,omitempty"`
+}
+
+// IncidentTypeFieldOptionData represents the data for a field option.
+type IncidentTypeFieldOptionData struct {
+	Value    string `json:"value,omitempty"`
+	DataType string `json:"data_type,omitempty"`
+}
+
+// ListIncidentTypeFieldsOptions contains the parameters for listing incident type fields.
+type ListIncidentTypeFieldsOptions struct {
+	Includes []string `url:"include,omitempty,brackets"`
+}
+
+// ListIncidentTypeFieldsResponse represents the response from listing incident type fields.
+type ListIncidentTypeFieldsResponse struct {
+	Fields []IncidentTypeField `json:"fields,omitempty"`
+}
+
+// ListIncidentTypeFields retrieves all custom fields for a specific incident type.
+func (c *Client) ListIncidentTypeFields(ctx context.Context, typeIDOrName string, o ListIncidentTypeFieldsOptions) (*ListIncidentTypeFieldsResponse, error) {
+	v, err := query.Values(o)
+	if err != nil {
+		return nil, err
+	}
+
+	resp, err := c.get(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields?"+v.Encode(), nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result ListIncidentTypeFieldsResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result, err
+}
+
+type incidentTypeFieldsResponse struct {
+	Field IncidentTypeField `json:"field"`
+}
+
+// CreateIncidentTypeFieldOptions contains the parameters for creating a new incident type field.
+type CreateIncidentTypeFieldOptions struct {
+	Name         string                    `json:"name"`
+	DisplayName  string                    `json:"display_name"`
+	DataType     string                    `json:"data_type"`  // boolean integer float string datetime url
+	FieldType    string                    `json:"field_type"` // single_value single_value_fixed multi_value multi_value_fixed
+	DefaultValue interface{}               `json:"default_value,omitempty"`
+	Description  *string                   `json:"description,omitempty"`
+	Enabled      *bool                     `json:"enabled,omitempty"`
+	FieldOptions []IncidentTypeFieldOption `json:"field_options,omitempty"`
+}
+
+// CreateIncidentTypeField creates a new custom field for a specific incident type.
+func (c *Client) CreateIncidentTypeField(ctx context.Context, typeIDOrName string, o CreateIncidentTypeFieldOptions) (*IncidentTypeField, error) {
+	d := map[string]CreateIncidentTypeFieldOptions{
+		"field": o,
+	}
+
+	resp, err := c.post(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields", d, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result incidentTypeFieldsResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result.Field, err
+}
+
+// GetIncidentTypeFieldOptions contains the parameters for retrieving a specific incident type field.
+type GetIncidentTypeFieldOptions struct {
+	Includes []string `url:"include,omitempty,brackets"`
+}
+
+// GetIncidentTypeField retrieves a specific custom field for an incident type.
+func (c *Client) GetIncidentTypeField(ctx context.Context, typeIDOrName string, fieldID string, o GetIncidentTypeFieldOptions) (*IncidentTypeField, error) {
+	v, err := query.Values(o)
+	if err != nil {
+		return nil, err
+	}
+
+	resp, err := c.get(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields/"+fieldID+"?"+v.Encode(), nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result incidentTypeFieldsResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result.Field, err
+}
+
+// UpdateIncidentTypeFieldOptions contains the parameters for updating an incident type field.
+type UpdateIncidentTypeFieldOptions struct {
+	DisplayName  *string      `json:"display_name,omitempty"`
+	Enabled      *bool        `json:"enabled,omitempty"`
+	DefaultValue *interface{} `json:"default_value,omitempty"`
+	Description  *string      `json:"description,omitempty"`
+}
+
+// UpdateIncidentTypeField updates an existing custom field for an incident type.
+func (c *Client) UpdateIncidentTypeField(ctx context.Context, typeIDOrName, fieldID string, o UpdateIncidentTypeFieldOptions) (*IncidentTypeField, error) {
+	d := map[string]UpdateIncidentTypeFieldOptions{
+		"field": o,
+	}
+
+	resp, err := c.put(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields/"+fieldID, d, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result incidentTypeFieldsResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result.Field, err
+}
+
+// DeleteIncidentTypeField removes a custom field from an incident type.
+func (c *Client) DeleteIncidentTypeField(ctx context.Context, typeIDOrName, fieldID string) error {
+	_, err := c.delete(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields/"+fieldID)
+	return err
+}
+
+// ListIncidentTypeFieldOptionsOptions contains the parameters for listing field options.
+type ListIncidentTypeFieldOptionsOptions struct{}
+
+// ListIncidentTypeFieldOptionsResponse represents the response from listing field options.
+type ListIncidentTypeFieldOptionsResponse struct {
+	FieldOptions []IncidentTypeFieldOption `json:"field_options,omitempty"`
+}
+
+// ListIncidentTypeFieldOptions retrieves all options for a specific custom field.
+func (c *Client) ListIncidentTypeFieldOptions(ctx context.Context, typeIDOrName, fieldID string, o ListIncidentTypeFieldOptionsOptions) (*ListIncidentTypeFieldOptionsResponse, error) {
+	resp, err := c.get(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields/"+fieldID+"/field_options", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result ListIncidentTypeFieldOptionsResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result, err
+}
+
+type incidentTypeFieldOptionsResponse struct {
+	FieldOption IncidentTypeFieldOption `json:"field_option,omitempty"`
+}
+
+// CreateIncidentTypeFieldOptionPayload contains the parameters for creating a new field option.
+type CreateIncidentTypeFieldOptionPayload struct {
+	Data *IncidentTypeFieldOptionData `json:"data,omitempty"`
+}
+
+// CreateIncidentTypeFieldOption creates a new option for a custom field.
+func (c *Client) CreateIncidentTypeFieldOption(ctx context.Context, typeIDOrName, fieldID string, o CreateIncidentTypeFieldOptionPayload) (*IncidentTypeFieldOption, error) {
+	d := map[string]CreateIncidentTypeFieldOptionPayload{
+		"field_option": o,
+	}
+
+	resp, err := c.post(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields/"+fieldID+"/field_options", d, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result incidentTypeFieldOptionsResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result.FieldOption, err
+}
+
+// GetIncidentTypeFieldOptionOptions contains the parameters for retrieving a specific field option.
+type GetIncidentTypeFieldOptionOptions struct{}
+
+// GetIncidentTypeFieldOption retrieves a specific option for a custom field.
+func (c *Client) GetIncidentTypeFieldOption(ctx context.Context, typeIDOrName, fieldID, fieldOptionID string, o GetIncidentTypeFieldOptionOptions) (*IncidentTypeFieldOption, error) {
+	resp, err := c.get(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields/"+fieldID+"/field_options/"+fieldOptionID, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result incidentTypeFieldOptionsResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result.FieldOption, err
+}
+
+// UpdateIncidentTypeFieldOptionPayload contains the parameters for updating a field option.
+type UpdateIncidentTypeFieldOptionPayload struct {
+	ID   string                       `json:"id,omitempty"`
+	Data *IncidentTypeFieldOptionData `json:"data,omitempty"`
+}
+
+// UpdateIncidentTypeFieldOption updates an existing option for a custom field.
+func (c *Client) UpdateIncidentTypeFieldOption(ctx context.Context, typeIDOrName, fieldID string, o UpdateIncidentTypeFieldOptionPayload) (*IncidentTypeFieldOption, error) {
+	d := map[string]UpdateIncidentTypeFieldOptionPayload{
+		"field_option": o,
+	}
+
+	resp, err := c.put(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields/"+fieldID+"/field_options/"+o.ID, d, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var result incidentTypeFieldOptionsResponse
+	err = c.decodeJSON(resp, &result)
+
+	return &result.FieldOption, err
+}
+
+// DeleteIncidentTypeFieldOption removes an option from a custom field.
+func (c *Client) DeleteIncidentTypeFieldOption(ctx context.Context, typeIDOrName, fieldID, fieldOptionID string) error {
+	_, err := c.delete(ctx, "/incidents/types/"+typeIDOrName+"/custom_fields/"+fieldID+"/field_options/"+fieldOptionID)
+	return err
+}


Test patch:
diff --git a/incident_type_test.go b/incident_type_test.go
new file mode 100644
index 0000000..067e1b9
--- /dev/null
+++ b/incident_type_test.go
@@ -0,0 +1,480 @@
+package pagerduty
+
+import (
+	"context"
+	"net/http"
+	"testing"
+)
+
+// Incident Type
+
+func TestIncidentType_List(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		_, _ = w.Write([]byte(`{"incident_types": [{"id": "PT1234", "name": "Test Type"}]}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+	want := &ListIncidentTypesResponse{
+		IncidentTypes: []IncidentType{
+			{
+				ID:   "PT1234",
+				Name: "Test Type",
+			},
+		},
+	}
+
+	res, err := client.ListIncidentTypes(context.Background(), ListIncidentTypesOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+	testEqual(t, want, res)
+}
+
+func TestIncidentType_Create(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		_, _ = w.Write([]byte(`{"incident_type": {"id": "PT1234", "name": "New Type", "enabled": true}}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+	enabled := true
+	input := CreateIncidentTypeOptions{
+		Name:        "New Type",
+		DisplayName: "New Type Display",
+		ParentType:  "incident",
+		Enabled:     &enabled,
+	}
+
+	res, err := client.CreateIncidentType(context.Background(), input)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &IncidentType{
+		ID:      "PT1234",
+		Name:    "New Type",
+		Enabled: true,
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentType_Get(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		_, _ = w.Write([]byte(`{"incident_type": {"id": "PT1234", "name": "Test Type"}}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+
+	res, err := client.GetIncidentType(context.Background(), "PT1234", GetIncidentTypeOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &IncidentType{
+		ID:   "PT1234",
+		Name: "Test Type",
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentType_Update(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "PUT")
+		_, _ = w.Write([]byte(`{"incident_type": {"id": "PT1234", "name": "Updated Type", "enabled": false}}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+	displayName := "Updated Type"
+	enabled := false
+	input := UpdateIncidentTypeOptions{
+		DisplayName: &displayName,
+		Enabled:     &enabled,
+	}
+
+	res, err := client.UpdateIncidentType(context.Background(), "PT1234", input)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &IncidentType{
+		ID:      "PT1234",
+		Name:    "Updated Type",
+		Enabled: false,
+	}
+
+	testEqual(t, want, res)
+}
+
+// Incident Type Field
+
+func TestIncidentTypeField_List(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		_, _ = w.Write([]byte(`{"fields": [{"id": "PF1234", "name": "Test Field"}]}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+
+	res, err := client.ListIncidentTypeFields(context.Background(), "PT1234", ListIncidentTypeFieldsOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &ListIncidentTypeFieldsResponse{
+		Fields: []IncidentTypeField{
+			{
+				ID:   "PF1234",
+				Name: "Test Field",
+			},
+		},
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentTypeField_Create(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		_, _ = w.Write([]byte(`{
+			"field": {
+				"id": "PF1234",
+				"name": "Test Field",
+				"display_name": "Test Field Display",
+				"data_type": "string",
+				"field_type": "single_value",
+				"enabled": true
+			}
+		}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+	enabled := true
+	input := CreateIncidentTypeFieldOptions{
+		Name:        "Test Field",
+		DisplayName: "Test Field Display",
+		DataType:    "string",
+		FieldType:   "single_value",
+		Enabled:     &enabled,
+	}
+
+	res, err := client.CreateIncidentTypeField(context.Background(), "PT1234", input)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &IncidentTypeField{
+		ID:          "PF1234",
+		Name:        "Test Field",
+		DisplayName: "Test Field Display",
+		DataType:    "string",
+		FieldType:   "single_value",
+		Enabled:     true,
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentTypeField_Get(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields/PF1234", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		_, _ = w.Write([]byte(`{
+			"field": {
+				"id": "PF1234",
+				"name": "Test Field",
+				"display_name": "Test Field Display",
+				"data_type": "string",
+				"field_type": "single_value",
+				"enabled": true
+			}
+		}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+
+	res, err := client.GetIncidentTypeField(context.Background(), "PT1234", "PF1234", GetIncidentTypeFieldOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &IncidentTypeField{
+		ID:          "PF1234",
+		Name:        "Test Field",
+		DisplayName: "Test Field Display",
+		DataType:    "string",
+		FieldType:   "single_value",
+		Enabled:     true,
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentTypeField_Update(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields/PF1234", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "PUT")
+		_, _ = w.Write([]byte(`{
+			"field": {
+				"id": "PF1234",
+				"name": "Test Field",
+				"display_name": "Updated Field Display",
+				"data_type": "string",
+				"field_type": "single_value",
+				"enabled": false
+			}
+		}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+	displayName := "Updated Field Display"
+	enabled := false
+	input := UpdateIncidentTypeFieldOptions{
+		DisplayName: &displayName,
+		Enabled:     &enabled,
+	}
+
+	res, err := client.UpdateIncidentTypeField(context.Background(), "PT1234", "PF1234", input)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &IncidentTypeField{
+		ID:          "PF1234",
+		Name:        "Test Field",
+		DisplayName: "Updated Field Display",
+		DataType:    "string",
+		FieldType:   "single_value",
+		Enabled:     false,
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentTypeField_Delete(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields/PF1234", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "DELETE")
+		w.WriteHeader(http.StatusNoContent)
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+
+	err := client.DeleteIncidentTypeField(context.Background(), "PT1234", "PF1234")
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+// Incident Type Field Option
+
+func TestIncidentTypeFieldOption_List(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields/PF1234/field_options", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		_, _ = w.Write([]byte(`{
+			"field_options": [
+				{
+					"id": "PFO123",
+					"type": "field_option",
+					"data": {
+						"value": "Option 1",
+						"data_type": "string"
+					}
+				}
+			]
+		}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+
+	res, err := client.ListIncidentTypeFieldOptions(context.Background(), "PT1234", "PF1234", ListIncidentTypeFieldOptionsOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &ListIncidentTypeFieldOptionsResponse{
+		FieldOptions: []IncidentTypeFieldOption{
+			{
+				ID:   "PFO123",
+				Type: "field_option",
+				Data: &IncidentTypeFieldOptionData{
+					Value:    "Option 1",
+					DataType: "string",
+				},
+			},
+		},
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentTypeFieldOption_Create(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields/PF1234/field_options", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		_, _ = w.Write([]byte(`{
+			"field_option": {
+				"id": "PFO123",
+				"type": "field_option",
+				"data": {
+					"value": "New Option",
+					"data_type": "string"
+				}
+			}
+		}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+	input := CreateIncidentTypeFieldOptionPayload{
+		Data: &IncidentTypeFieldOptionData{
+			Value:    "New Option",
+			DataType: "string",
+		},
+	}
+
+	res, err := client.CreateIncidentTypeFieldOption(context.Background(), "PT1234", "PF1234", input)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &IncidentTypeFieldOption{
+		ID:   "PFO123",
+		Type: "field_option",
+		Data: &IncidentTypeFieldOptionData{
+			Value:    "New Option",
+			DataType: "string",
+		},
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentTypeFieldOption_Get(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields/PF1234/field_options/PFO123", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		_, _ = w.Write([]byte(`{
+			"field_option": {
+				"id": "PFO123",
+				"type": "field_option",
+				"data": {
+					"value": "Option 1",
+					"data_type": "string"
+				}
+			}
+		}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+
+	res, err := client.GetIncidentTypeFieldOption(context.Background(), "PT1234", "PF1234", "PFO123", GetIncidentTypeFieldOptionOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &IncidentTypeFieldOption{
+		ID:   "PFO123",
+		Type: "field_option",
+		Data: &IncidentTypeFieldOptionData{
+			Value:    "Option 1",
+			DataType: "string",
+		},
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentTypeFieldOption_Update(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields/PF1234/field_options/PFO123", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "PUT")
+		_, _ = w.Write([]byte(`{
+			"field_option": {
+				"id": "PFO123",
+				"type": "field_option",
+				"data": {
+					"value": "Updated Option",
+					"data_type": "string"
+				}
+			}
+		}`))
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+	input := UpdateIncidentTypeFieldOptionPayload{
+		ID: "PFO123",
+		Data: &IncidentTypeFieldOptionData{
+			Value:    "Updated Option",
+			DataType: "string",
+		},
+	}
+
+	res, err := client.UpdateIncidentTypeFieldOption(context.Background(), "PT1234", "PF1234", input)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &IncidentTypeFieldOption{
+		ID:   "PFO123",
+		Type: "field_option",
+		Data: &IncidentTypeFieldOptionData{
+			Value:    "Updated Option",
+			DataType: "string",
+		},
+	}
+
+	testEqual(t, want, res)
+}
+
+func TestIncidentTypeFieldOption_Delete(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/incidents/types/PT1234/custom_fields/PF1234/field_options/PFO123", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "DELETE")
+		w.WriteHeader(http.StatusNoContent)
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+
+	err := client.DeleteIncidentTypeFieldOption(context.Background(), "PT1234", "PF1234", "PFO123")
+	if err != nil {
+		t.Fatal(err)
+	}
+}