---
title: "Retrieve an application's form definition and state together"
method: POST
path: "/state/with-definition"
tags: ["State"]
---

# Retrieve an application's form definition and state together

`POST /state/with-definition`

Returns the resolved form definition and the matching application state in a single call.
When no state exists, the latest active definition is returned with `state: null` (the
frontend creates the state). When state exists, the latest active definition within the
state's pinned major is resolved; if it is newer than the stored version, the state's
version fields are upgraded.

Unlike the other `/state` routes, this endpoint does NOT enforce the lock via a
pre-handler. Because it is partly responsible for resolving the `grantVersion`, a cold
first call cannot yet carry a version-bearing token. The lock token is still required
(it identifies the owner), but its `grantVersion` claim is optional: the endpoint
resolves the authoritative version and then acquires/refreshes the application lock
against that resolved version, returning `423` if another owner holds it. When a
version upgrade is persisted, the now-orphaned lock on the previous version is released
on a best-effort basis (any failure is ignored and that lock simply expires via its TTL).

The response always includes an `upgraded` boolean indicating whether a version upgrade
was persisted on this call. When `upgraded` is `true`, `fromVersion` and `toVersion`
report the previous and new `grantVersion` respectively.

Set `includeDefinition: false` in the request body for a state-only read: the caller
already holds the form definition locally (e.g. a legacy YAML-sourced form), so the
backend skips all definition resolution and version-upgrade work and returns only the
stored state (and its version) with no `definition` payload. In that mode the lock is
acquired against the state's existing version, and a `404` is never returned (a missing
state simply yields `state: null`).

## Request body

- StateWithDefinitionRequest
  - `sbi` string, required
  - `grantCode` string, required
  - `includeDefinition` boolean — When `true` (the default) the resolved form definition is returned alongside the state. When `false` the caller already holds the form definition locally (e.g. a legacy YAML-sourced form), so the backend skips all definition resolution and version-upgrade work and returns only the stored state (and its version) with no `definition` payload.

## Response `200`

The resolved form definition and the application state (state may be null). The `upgraded` flag reports whether a grant version upgrade was persisted as a side effect of this call.

- StateWithDefinitionResponse
  - `definition` FormDefinition — A grant form definition document
    - `grantCode` string
    - `id` string
    - `title` string
    - `major` integer
    - `minor` integer
    - `patch` integer
    - `status` string
    - `definition` object
  - `state` object, nullable, required — The application state, or null when no state exists yet
  - `upgraded` boolean, required — True when this call persisted a grant version upgrade on the stored state as a side effect; false when the call was read-only or no state existed yet. The application lock is always acquired against the resolved version; on an upgrade the previous version's lock is released best-effort (failures ignored, otherwise reaped by its TTL).
  - `fromVersion` string — The previous `grantVersion` before the upgrade. Present only when `upgraded` is true.
  - `toVersion` string — The new `grantVersion` the state was upgraded to. Present only when `upgraded` is true.

## Other responses

- `400` — Validation error or missing lock token claims
- `401` — Missing or invalid application lock token
- `404` — No form definition found. Only returned when `includeDefinition` is `true`; state-only reads never return `404`.
- `423` — The application lock is held by another owner
- `500` — Failed to retrieve state with form definition

## Changes

- **2026-06-29** `047f9b2e19c3` — 1 warning, 1 info
  - deleted the `header` request parameter `x-application-lock-owner`
  - the endpoint scheme security `bearerAuth AND lockToken` was added to the API
- **2026-06-22** `ee7387c4a16a` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/defra/apis/grants-ui-backend-api/changes/state/with-definition/post.md)

---

[API](https://skmtc.dev/defra/apis/grants-ui-backend-api.md) · [All operations](https://skmtc.dev/defra/apis/grants-ui-backend-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/defra/grants-ui-backend-api/revisions/09665d03cacb/schema)
