> For the complete documentation index, see [llms.txt](https://docs.agilecase.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.agilecase.com/developer-documentation/case-data-api/response-format.md).

# Response Format

Every request returns the same envelope: a status, a message, and a `data` object holding the results grouped by kind.

```json
{
  "status": "success",
  "message": "",
  "data": {
    "caseFields": [
      {
        "name": "CaseReference",
        "value": "CASE-1042",
        "type": "Text",
        "originalName": "case.CaseReference"
      }
    ],
    "customFields": [
      {
        "id": 6364,
        "name": "Customer Rating",
        "value": "75",
        "type": "Textbox",
        "originalName": "custom.CustomerRating"
      }
    ]
  }
}
```

## Which group a value lands in

Results are grouped by the kind of data, not by the order you asked for them.

<table><thead><tr><th width="230">Requested as</th><th>Appears in</th></tr></thead><tbody><tr><td><code>custom.</code>, <code>client.custom.</code>, <code>source.custom.</code></td><td><code>data.customFields</code></td></tr><tr><td><code>case.</code>, <code>contact.</code></td><td><code>data.caseFields</code></td></tr><tr><td><code>casetable.</code></td><td><code>data.customTables</code></td></tr></tbody></table>

{% hint style="warning" %}
A group is left out of the response entirely when it holds nothing, rather than being returned as an empty array. Code such as `data.data.customFields[0].value` therefore throws when nothing matched, which is a common cause of a script that works until a field is renamed. Check the group exists before reading from it.
{% endhint %}

## Fields on a value

<table><thead><tr><th width="180">Property</th><th>What it holds</th></tr></thead><tbody><tr><td><code>value</code></td><td>The value as text. Always a string, even for numbers and dates.</td></tr><tr><td><code>name</code></td><td>The field's real name, as configured.</td></tr><tr><td><code>id</code></td><td>The custom field's numeric ID. Not present for case or contact fields.</td></tr><tr><td><code>type</code></td><td>The field type, such as <code>Textbox</code> or <code>DatePicker</code>. Case and contact fields report <code>Text</code>, or <code>DateTime</code> for the two case date fields.</td></tr><tr><td><code>originalName</code></td><td>The token you asked for, echoed back.</td></tr><tr><td><code>error</code></td><td>Present only when that value could not be provided.</td></tr></tbody></table>

Any property that has no value is left out rather than returned as `null`.

### Matching results to what you asked for

`originalName` is the reliable way to find a value, because it echoes your own token. Position is not reliable, since results are grouped and a single custom field name can match more than one field.

```javascript
function valueOf(response, token) {
    var groups = [response.data.customFields, response.data.caseFields];
    for (var g = 0; g < groups.length; g++) {
        var items = groups[g] || [];
        for (var i = 0; i < items.length; i++) {
            if (items[i].originalName.toLowerCase() === token.toLowerCase()) {
                return items[i].error ? null : items[i].value;
            }
        }
    }
    return null;
}
```

Compare case-insensitively. The echoed token does not always preserve the capitalisation you used.

## How values are formatted

<table><thead><tr><th width="230">Field type</th><th>What you get</th></tr></thead><tbody><tr><td>Dates, dropdowns and checkbox lists</td><td>The value as displayed to a user, rather than the raw stored value.</td></tr><tr><td>Calculated fields</td><td>Evaluated at the moment you ask, so the value is current.</td></tr><tr><td>Everything else</td><td>The stored value, with any surrounding brackets or quotation marks removed.</td></tr></tbody></table>

A field that exists but has no value on this case returns its configured default, or an empty string if it has none.

## Tables

A table comes back with all of its rows, and each row with all of its columns:

```json
{
  "status": "success",
  "message": "",
  "data": {
    "customTables": [
      {
        "id": 1176,
        "name": "Risk Assessments",
        "rows": [
          {
            "id": 1,
            "author": "Jane Smith",
            "dateCreated": "2026-03-14T09:21:00",
            "items": [
              { "name": "Assessed On", "value": "14/03/2026", "type": "DatePicker" },
              { "name": "Outcome", "value": "Low", "type": "Dropdown" }
            ]
          }
        ]
      }
    ]
  }
}
```

Rows carry who created them and when. Note that the items inside a row have no `id` or `originalName`, so columns are identified by `name` only, and they appear in the order the columns are configured.

## Errors

There are two kinds, and they are reported differently. Both come back with an HTTP status of 200, so a failed request still looks successful to code that only checks the status code.

### A problem with one value

The rest of the request still succeeds. The failing entry appears with an `error` and usually no `value`:

```json
{
  "status": "success",
  "message": "",
  "data": {
    "customFields": [
      { "name": "CustomerRatng", "originalName": "custom.CustomerRatng",
        "error": "CustomField with name 'CustomerRatng' not found." }
    ]
  }
}
```

Note that `status` is still `success`. Per-value problems do not change it, so checking `status` alone is not enough. You have to check each value for an `error`.

<table><thead><tr><th width="330">Error</th><th>Cause</th></tr></thead><tbody><tr><td><code>CustomField with name '…' not found.</code></td><td>No custom field of that name exists.</td></tr><tr><td><code>CustomField with id … not found.</code></td><td>No custom field with that ID is available on this case type.</td></tr><tr><td><code>… is invalid field name.</code></td><td>A <code>case.</code> or <code>contact.</code> field name that is not in the <a href="/pages/zYsLHGyyGcthViJRQ6cP">Field Reference</a>, including one whose capitalisation is wrong.</td></tr><tr><td><code>… is empty or null.</code></td><td>The field is valid but holds nothing on this case.</td></tr><tr><td><code>Contact field with name '…' not found.</code></td><td>No contact is linked to the case with that relationship.</td></tr><tr><td><code>CustomTableField with name or id … not found.</code></td><td>No table group of that name or ID, or the group exists but is not a table.</td></tr></tbody></table>

### A problem with the whole request

Nothing is returned. `status` becomes `fail` and `message` explains why:

```json
{
  "status": "fail",
  "message": "Case with id 1042 not exist in DB or you don't have permission;",
  "data": {}
}
```

<table><thead><tr><th width="380">Message</th><th>Cause</th></tr></thead><tbody><tr><td><code>You are not authorized;</code></td><td>No signed-in session. Usually means the session expired while the page was open.</td></tr><tr><td><code>Property getValues is empty or null;</code></td><td><code>getValues</code> was missing or empty.</td></tr><tr><td><code>Case with id … not exist in DB or you don't have permission;</code></td><td>No such case, or the signed-in user cannot see it. The two are deliberately not distinguished.</td></tr></tbody></table>

## Checking a response properly

Because failures arrive with a 200 and a partial success keeps `status` as `success`, a robust script checks both levels:

```javascript
$.get('/api/case/' + caseid + '/data?getValues=custom.CustomerRating', function (data) {
    if (data.status !== 'success') {
        console.log('Case Data API request failed: ' + data.message);
        return;
    }

    var fields = data.data.customFields || [];
    if (!fields.length || fields[0].error) {
        console.log('Rating unavailable: ' + (fields.length ? fields[0].error : 'not returned'));
        return;
    }

    // safe to use fields[0].value
});
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.agilecase.com/developer-documentation/case-data-api/response-format.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
