> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.thepennyinc.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.thepennyinc.com/_mcp/server.

# Resource Versions & Concurrency

Many Penny resources include version metadata:

| Field          | Meaning                                        |
| -------------- | ---------------------------------------------- |
| `version`      | The version of the resource returned by Penny. |
| `version_time` | The time associated with that version.         |

These fields help identify which state of a resource you are working with and when that state was produced.

## Resource versions

Each update to a versioned resource produces a new current version.

For example:

```json
{
  "spend_control_id": "spend_control_...",
  "version": 4,
  "version_time": "2026-09-14T02:31:18Z"
}
```

You can use version information for:

* detecting changes;
* maintaining local caches or projections;
* audit and reconciliation workflows;
* identifying the state represented by a response or event.

The highest current version represents the latest state of the resource.

## Reading historical versions

Some Penny resources allow you to retrieve an earlier version directly.

For example, where supported:

```http
GET /spend_controls/{spend_control_id}?version=3
```

If you omit `version`, or send `version=0`, Penny returns the latest version. Versions start at `1`.

Historical-version access is resource-specific. Check the API reference for the operations that accept a `version` parameter. To see every version of a resource, use its `/history` endpoint where one exists.

## Concurrent updates

Penny protects resources from conflicting concurrent writes.

If two updates affecting the same resource are processed at the same time, one of the operations may be rejected with:

```text
409 Conflict
```

This prevents an update from silently overwriting a newer resource state.

You do not send the resource version with an update request, and Penny does not use `ETag` or `If-Match` headers. Penny checks for concurrent changes on each write.

## Handling `409 Conflict`

A `409 Conflict` on an update means the resource changed between the moment Penny read it and the moment it tried to write your change. The response `details` include `object_type`, `object_id`, `expected_version`, and `found_version`.

A `409` can also mean a request with the same `Idempotency-Key` is still being processed. See [Retries & Idempotency](/get-started/idempotency) for that case.

When you receive a `409`:

1. retrieve the latest version of the resource;
2. review its current state;
3. determine whether your intended change is still required;
4. submit the change again against the latest state.

```mermaid
sequenceDiagram
    participant A as User A
    participant P as Penny
    participant B as User B

    A->>P: Update resource
    B->>P: Update same resource

    P-->>A: Update succeeds
    P-->>B: 409 Conflict

    B->>P: Read latest resource
    P-->>B: Latest version

    B->>B: Reapply intended change
    B->>P: Retry update
    P-->>B: Update succeeds
```

> **Info**
>
> A `409` is recoverable when the intended change is still valid. Re-read the latest resource state, reapply your intended change, and retry.

## Resource versions and events

Resource versions are useful when processing webhook or asynchronous updates because they let you identify which state of a resource an event relates to.

For integrations that maintain their own local copy of Penny resources, compare the incoming resource version with the version you already hold before updating your local state.

This protects against older events or responses replacing newer data in your system.

## Resource version vs webhook schema version

A resource's `version` is different from a webhook's `schema_version`.

```text
Resource version
→ identifies the state of a Penny resource

Webhook schema_version
→ identifies the schema used for the webhook payload
```

For example:

```json
{
  "schema_version": "1.0"
}
```

These values serve different purposes. Do not compare them.

See [Webhooks Overview](/platform/webhooks-overview) for webhook delivery and schema information.

## Related guidance

* [Errors & Rate Limits](/get-started/errors) — handling `409` and other API responses.
* [Retries & Idempotency](/get-started/idempotency) — retrying operations safely.
* [Webhooks Overview](/platform/webhooks-overview) — event delivery and resource updates.