## Get field value history

`client.Opportunity.FieldHistory(ctx, fieldKey, params) (*OpportunityFieldHistoryResponse, error)`

**get** `/v1/opportunities/{id}/fields/{fieldKey}/history`

Returns the value-change history for a single field on a record, newest first. Consecutive identical values are collapsed. History is cursor-paginated: pass `nextCursor` from the previous response as `after` to page through older values. Only attribute-backed fields (custom attributes and attribute-backed system fields) have history — column-backed system fields return an error.

**[Required scope](/using-the-api/scopes/):** `opportunities:read`

**[Rate limit category](/using-the-api/rate-limits/):** Read

### Parameters

- `fieldKey string`

  Field key whose value history to return. System fields use a `$` prefix (e.g. `$status`); custom attributes use their bare slug.

- `params OpportunityFieldHistoryParams`

  - `ID param.Field[string]`

    Path param: Unique identifier of the record.

  - `After param.Field[string]`

    Query param: Cursor from a previous response’s `nextCursor` to fetch the next page.

  - `Limit param.Field[int64]`

    Query param: Maximum number of history entries to return. Defaults to 20, maximum 100.

### Returns

- `type OpportunityFieldHistoryResponse struct{…}`

  - `Data []OpportunityFieldHistoryResponseData`

    Recorded values for the field, newest first.

    - `DisplayValue string`

      Human-readable rendering of the value (e.g. a select option label), suitable for display.

    - `IsCreate bool`

      True for the record’s original value. Only set when the full history fits in the response (never on a truncated/paginated page).

    - `RecordedAt string`

      ISO 8601 timestamp of when this value was recorded.

    - `Value OpportunityFieldHistoryResponseDataValueUnion`

      The field value, or null if unset.

      - `string`

      - `float64`

      - `bool`

      - `type OpportunityFieldHistoryResponseDataValueArray []string`

      - `type OpportunityFieldHistoryResponseDataValueAddress struct{…}`

        - `City string`

          City name.

        - `Country string`

          2-letter ISO 3166-1 alpha-2 country code.

        - `Latitude float64`

          Latitude coordinate.

        - `Longitude float64`

          Longitude coordinate.

        - `PostalCode string`

          Postal or ZIP code.

        - `State string`

          State or province.

        - `Street string`

          Street address line 1.

        - `Street2 string`

          Street address line 2.

      - `type OpportunityFieldHistoryResponseDataValueFullName struct{…}`

        - `FirstName string`

          The contact's first name.

        - `LastName string`

          The contact's last name.

    - `ValueType string`

      The data type of the field.

      - `const OpportunityFieldHistoryResponseDataValueTypeAddress OpportunityFieldHistoryResponseDataValueType = "ADDRESS"`

      - `const OpportunityFieldHistoryResponseDataValueTypeCheckbox OpportunityFieldHistoryResponseDataValueType = "CHECKBOX"`

      - `const OpportunityFieldHistoryResponseDataValueTypeCurrency OpportunityFieldHistoryResponseDataValueType = "CURRENCY"`

      - `const OpportunityFieldHistoryResponseDataValueTypeDatetime OpportunityFieldHistoryResponseDataValueType = "DATETIME"`

      - `const OpportunityFieldHistoryResponseDataValueTypeEmail OpportunityFieldHistoryResponseDataValueType = "EMAIL"`

      - `const OpportunityFieldHistoryResponseDataValueTypeFullName OpportunityFieldHistoryResponseDataValueType = "FULL_NAME"`

      - `const OpportunityFieldHistoryResponseDataValueTypeMarkdown OpportunityFieldHistoryResponseDataValueType = "MARKDOWN"`

      - `const OpportunityFieldHistoryResponseDataValueTypeMultiSelect OpportunityFieldHistoryResponseDataValueType = "MULTI_SELECT"`

      - `const OpportunityFieldHistoryResponseDataValueTypeNumber OpportunityFieldHistoryResponseDataValueType = "NUMBER"`

      - `const OpportunityFieldHistoryResponseDataValueTypeSingleSelect OpportunityFieldHistoryResponseDataValueType = "SINGLE_SELECT"`

      - `const OpportunityFieldHistoryResponseDataValueTypeSocialHandle OpportunityFieldHistoryResponseDataValueType = "SOCIAL_HANDLE"`

      - `const OpportunityFieldHistoryResponseDataValueTypeTelephone OpportunityFieldHistoryResponseDataValueType = "TELEPHONE"`

      - `const OpportunityFieldHistoryResponseDataValueTypeText OpportunityFieldHistoryResponseDataValueType = "TEXT"`

      - `const OpportunityFieldHistoryResponseDataValueTypeURL OpportunityFieldHistoryResponseDataValueType = "URL"`

      - `const OpportunityFieldHistoryResponseDataValueTypeHTML OpportunityFieldHistoryResponseDataValueType = "HTML"`

  - `HasMore bool`

    Whether more history exists beyond this page.

  - `NextCursor string`

    Cursor to pass as `after` to fetch the next page, or null when there are no more entries.

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/Lightfld/lightfield-go"
  "github.com/Lightfld/lightfield-go/option"
)

func main() {
  client := githubcomlightfldlightfieldgo.NewClient(
    option.WithAPIKey("My API Key"),
  )
  opportunityFieldHistoryResponse, err := client.Opportunity.FieldHistory(
    context.TODO(),
    "fieldKey",
    githubcomlightfldlightfieldgo.OpportunityFieldHistoryParams{
      ID: "id",
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", opportunityFieldHistoryResponse.Data)
}
```

#### Response

```json
{
  "data": [
    {
      "displayValue": "displayValue",
      "isCreate": true,
      "recordedAt": "recordedAt",
      "value": "string",
      "valueType": "ADDRESS"
    }
  ],
  "hasMore": true,
  "nextCursor": "nextCursor"
}
```
