# Field Types and What the APIs Return

> Source: https://agilitycms.com/docs/developers/field-types-api-reference

When you add a field to a content model or component model, you choose a field type. This page shows what each field type looks like in the JSON your code receives from the **Content Fetch API** (REST) and the **GraphQL API**, so you know how to read it.

For what each field type does in the editor (options, limits, validation), see [Fields](/docs/developers/fields). For the linked content variants, see [Linked Content Field Types](/docs/developers/linked-content-field-types).

## How field names appear in responses

Both APIs return field values inside a `fields` object, keyed by the field's reference name with the **first letter lowercased**. A field named `Title` comes back as `title`, `MarketingCta1` as `marketingCta1`, and a field named `URL` as `uRL`.

```json
{
  "contentID": 124,
  "properties": {
    "state": 2,
    "modified": "2021-04-01T10:15:59.907",
    "versionID": 916,
    "referenceName": "posts",
    "definitionName": "Post",
    "itemOrder": 3
  },
  "fields": {
    "title": "Virtual Tours - Ways to Travel From Home"
  }
}
```

In GraphQL you select the same names inside `fields { ... }`. A container is queried by its reference name in lowercase, with any character that isn't a letter, number or underscore replaced by `_` (so `ManagementSDK-Articles` becomes `managementsdk_articles`).

Empty fields: in GraphQL an empty Text field comes back as `null`, while an empty URL field can come back as an object with empty values. Don't assume every field is present on every item in either API; read fields defensively.

## Quick reference

| Field type | Fetch API (REST) | GraphQL |
| --- | --- | --- |
| Text | string | string, or `null` when empty |
| Multi-Line Text | string | string |
| HTML | string of HTML | string of HTML |
| Drop-down List | string: the selected choice's value | string: the selected choice's value |
| URL | object with `href` and `text` | object: select `text`, `href`, `target` |
| Date/Time | string (see [Dates](#datetime)) | string (see [Dates](#datetime)) |
| True/False | see [True/False](#truefalse) | see [True/False](#truefalse) |
| Image | object: `url`, `label`, size and dimensions | object |
| File, List of Files | see [File](#file-and-list-of-files) | see [File](#file-and-list-of-files) |
| Gallery | see [Gallery](#gallery) | see [Gallery](#gallery) |
| Linked Content | object or array of items, or a `referencename` stub, depending on depth | object or array of items |
| Hidden companion fields (`_ValueField`, `_TextField`) | string | see [Companion fields](#companion-fields-_valuefield-and-_textfield) |

The sections below show real responses for each type.

## Text

A single line of text. Returned as a string.

```json
"title": "Virtual Tours - Ways to Travel From Home"
```

In GraphQL an empty Text field is `null`. This is from the Agility docs instance's own changelog, where the optional `LinkURL` Text field is empty on one item and set on another:

```json
"linkURL": null
```

```json
"linkURL": "https://www.nuget.org/packages/Agility.NET.FetchAPI/3.1.0"
```

## Multi-Line Text

Multiple lines of plain text. Returned as a string, the same as Text. It is plain text, not HTML, so escape it like any other text when you render it.

```json
"description": "Fixed an issue in Agility.NET.FetchAPI where GetContentByGraphQL always queried en-us, whatever locale was passed."
```

## HTML

The rich text editor. Returned as a string of HTML, ready to render. Sanitize it if your app requires that, and render it as HTML rather than as text.

```json
"content": "<p>Virtual tours can open up amazing and awe-inspiring locations around the world...</p>\r\n<h2>Picking the Right Virtual Tour for You</h2>"
```

In this example, image tags inside the HTML point straight at the asset CDN, for example `<img src="https://cdn.aglty.io/..." />`.

## Markdown

Markdown content is returned as a plain string of Markdown. The API does not convert it to HTML: render it in your app with a Markdown library. On the Agility docs instance, new article bodies are stored this way, in a field named `MarkdownContent`:

```json
"markdownContent": "# Verifying Signed Webhooks ..."
```

The docs site reads that string and renders it to HTML on its own server.

Choose Markdown over HTML when your front end controls all the styling and you want content that is easy to diff, store in Git or hand to AI tools. Choose HTML when editors need the visual rich text editor.

## Drop-down List

Returns the **value** of the selected choice as a string, not its label. On the Agility docs instance, the `Icon` drop-down of the `Link` model has choices such as label `Content Fetch API` with value `content-fetch`, and label `.NET` with value `dotnet`. GraphQL returns the values:

```json
"icon": "content-fetch"
```

```json
"icon": "dotnet"
```

The Fetch API also returns the value. On the same instance, `FeatureCard` items whose `Accent` choices are labelled `Secondary (blue)` and `Tertiary (yellow)` come back from a content list request as `"accent": "secondary"` and `"accent": "tertiary"`.

Store values your code can switch on, and keep labels for editors.

## URL

Returns an object with the link text and address. In GraphQL, select the parts you need:

```graphql
{
  header {
    fields {
      primaryDropdownLinks(sort: "properties.itemOrder") {
        fields {
          link { text href }
          icon
        }
      }
    }
  }
}
```

Each link in the response (from the Agility docs instance) looks like this:

```json
"link": {
  "text": "Content Fetch API",
  "href": "/developers/content-fetch-api"
}
```

The Fetch API returns the same kind of object, for example:

```json
"cta1": {
  "href": "/contact-us",
  "text": "Get started"
}
```

You can also select `target` when the link is set to open in a new window. An empty URL field can still come back as an object, so test that `href` has a value rather than testing the object itself.

## Date/Time

The two APIs format dates differently.

**Fetch API:** an ISO 8601 string with a UTC offset.

```json
"date": "2021-03-31T13:17:50+00:00"
```

**GraphQL:** a date and time string in `M/D/YYYY h:mm:ss AM` format. This is from the Agility docs instance's changelog, where `Date` is a date-only field (the "Include Time" option is off):

```json
"date": "10/1/2026 4:00:00 AM"
```

Parse dates explicitly rather than relying on the default `Date` parser of your language, and decide how you will display date-only values so a time zone shift doesn't move them to the previous or next day. You can sort on dates in both APIs, for example `sort: "fields.date", direction: "desc"` in GraphQL.

## True/False

A Boolean field can be used in filters with an unquoted `true` or `false`. For example, this GraphQL query (used on the Agility docs changelog page) leaves out items marked internal:

```graphql
changes(take: 250, filter: "fields.internalOnly[ne]true") {
  contentID
  fields { title }
}
```

When you read the value itself, accept both a boolean `true` and the string `"true"` until you have checked the response from your own instance.

## Image

Returns an object with the asset URL, its label (alt text) and its size:

```json
"image": {
  "label": "Virtual Tour",
  "url": "https://cdn.aglty.io/blog-starter-2021-template/posts/virtual-tour_20210331171226_0.jpg",
  "target": null,
  "filesize": 279207,
  "pixelHeight": "1542",
  "pixelWidth": "2048",
  "height": 1542,
  "width": 2048
}
```

Note that `pixelHeight` and `pixelWidth` are strings while `height` and `width` are numbers. Use `label` as the image's `alt` text. To resize or convert the image, add query string parameters to `url` (see [Transforming Images Using Query Strings](/docs/editors/transforming-images-using-query-strings)).

In GraphQL, if the image processor could not work out an image's height or width, those values are `0`.

## File and List of Files

A File field holds a single uploaded file (for example a PDF or a video), and a List of Files field holds several. Like Image, the value points at the asset CDN. We have not yet published a verified response for these two types, so request an item that uses the field and inspect the JSON before you rely on a property name.

## Gallery

A Gallery field lets editors pick several images as a media gallery. To get a gallery's images, call the gallery endpoint with the gallery ID:

```bash
curl "https://api.aglty.io/{guid}/fetch/gallery/{id}" -H "APIKey: {your-key}"
```

The response describes the gallery and its media:

```json
{
  "galleryId": 12,
  "name": "Product shots",
  "description": "",
  "count": 2,
  "media": [
    {
      "mediaID": 401,
      "fileName": "front.jpg",
      "url": "https://cdn.aglty.io/{instance}/front.jpg",
      "size": 183004,
      "modifiedOn": "2026-01-15T10:00:00",
      "metaData": {}
    }
  ]
}
```

This example shape follows the Fetch API specification. The values are illustrative.

## Linked Content

Linked content fields connect an item to other content. What you get back depends on the field's settings and on your request.

### Fetch API: depth and expansion

By default (`ContentLinkDepth=1`), a field that links to a **whole list** comes back as a stub with the list's reference name, so you can fetch it separately:

```json
"field": {
  "referencename": "example1"
}
```

With `ExpandAllContentLinks=true`, the same field comes back as an array of items. `ContentLinkDepth` (default 1, maximum 5) controls how many levels of linked content are expanded. See [Content Link Depth](/docs/developers/content-fetch-api) for worked examples.

A field that links to **one selected item** (for example a Shared Dropdown List) comes back as the full linked item when it is within the requested depth:

```json
"category": {
  "contentID": 110,
  "properties": {
    "state": 2,
    "referenceName": "categories",
    "definitionName": "Category",
    "itemOrder": 1
  },
  "fields": { "title": "Travel Guide" }
},
"categoryID": "110"
```

### Companion fields: `_ValueField` and `_TextField`

Dropdown, checkbox and search list box linked fields save the selection into hidden companion fields. You name them in the field's settings (new ones are usually called `{Field}_ValueField` and `{Field}_TextField`; the `categoryID` field in the example above is a value field with a custom name). In the Fetch API their values are plain strings:

- The value field holds the selected content ID, or a comma-separated list of IDs for multi-select fields (for example `"110"` or `"32,45,65"`).
- The text field holds the display text of the selection.

Companion fields are the cheapest way to filter by a relationship, because you don't need to expand anything:

```text
fields.category_ValueField[eq]"110"
fields.tags_ValueField[contains]"32,45"
```

Compare companion values as strings. In JavaScript, `"110" == 110` is true but `"110" === 110` is not.

### GraphQL: select the linked items

In GraphQL you select linked content like any other object, and list fields accept `take`, `skip`, `sort` and `filter`. This query and its response come from the Agility docs instance's changelog. `changes` is a Nested Grid and `tags` is a Shared Search List Box:

```graphql
{
  changelog(take: 250, sort: "fields.date", direction: "desc") {
    contentID
    fields {
      date
      description
      changes(take: 250, filter: "fields.internalOnly[ne]true") {
        contentID
        properties { itemOrder }
        fields {
          tags { contentID fields { title } }
          title
          linkURL
        }
      }
    }
  }
}
```

```json
{
  "contentID": 1709,
  "fields": {
    "date": "9/30/2026 4:00:00 AM",
    "description": ".NET Fetch SDK 3.1 and a Management SDK for .NET Fix",
    "changes": [
      {
        "contentID": 1715,
        "properties": { "itemOrder": 0 },
        "fields": {
          "tags": [{ "contentID": 732, "fields": { "title": "Bugs" } }],
          "title": ".NET Fetch SDK 3.1: GraphQL Uses the Requested Locale",
          "linkURL": "https://www.nuget.org/packages/Agility.NET.FetchAPI/3.1.0"
        }
      }
    ]
  }
}
```

Multi-select linked fields (`tags` above) return an **array** of items, even when only one item is selected.

> [!NOTE]
> GraphQL container lists return 50 items by default. Pass `take` (up to 250), and pass it on nested lists too when they can be long.

## Fields that never reach the API as content

- **Tabs** only group fields in the editor.
- **Custom Section** fields show HTML to editors inside the CMS and are not part of your content.

## Custom fields

A custom field gives editors a custom interface for entering a value. What the API returns depends on what that custom field saves, so check the custom field's documentation, or fetch an item and inspect it.

## Related

- [Fields](/docs/developers/fields)
- [Linked Content Field Types](/docs/developers/linked-content-field-types)
- [Content Fetch API](/docs/developers/content-fetch-api)
- [GraphQL API](/docs/developers/graphql-api)
- [GraphQL & Rest API Filtering](/docs/developers/graphql-operators)
- [Fetch API Status Codes and Caching](/docs/developers/fetch-api-status-codes-and-caching)
