---
title: "POST /harness/sessions/{sessionId}/sync"
description: Sync session state
full: true
---

**Auth:** required. Send an `ivy_` API key (`Authorization: Bearer ivy_…` or `X-Ivy-Api-Key`), a Clerk session JWT (`Authorization: Bearer …`) or the Clerk `__session` cookie (browser sessions). See [Authentication](/docs/api/authentication).

Push local changes to the server using version vectors for conflict detection.

Conflict resolution modes:
- `merge` (default) — LWW; returns `conflicts` array when true concurrent edits detected
- `force_local` — client state wins unconditionally
- `force_remote` — server state wins; response includes full `state`

## Request

#### Path parameters

- `sessionId` (string (uuid)) —
Session UUID (UUIDv7 — time-ordered)

#### Request body

- `clientId` (string) —
Identifier of the client submitting changes

- `localVersion` (integer) —
Client's last-known session version number

- `localVector` (object) —
Map of clientId → logical clock counter. Used for conflict detection in multi-client sync.

- `localChanges` (object[]) —
Changes to apply — empty array performs a read-only pull

- `mode` (enum (&quot;merge&quot; | &quot;force_local&quot; | &quot;force_remote&quot;)) —

## Responses

### `200` OK

Sync applied or conflict returned

Response shape:

- `status` (enum (&quot;success&quot; | &quot;conflict&quot; | &quot;error&quot;)) —

- `newVersion` (integer) —
Server version after applying changes

- `newVector` (object) —
Map of clientId → logical clock counter. Used for conflict detection in multi-client sync.

- `remoteChanges` (object[]) —
Changes from the server not yet seen by this client

- `fullState` (object) —
Full session state snapshot persisted in Supabase

#### fullState properties

- `id` (string (uuid)) —

- `version` (integer) —

- `schemaVersion` (integer) —

- `userId` (string) —

- `organizationId` (string) —

- `messages` (object[]) —

- `pendingToolCalls` (object[]) —

- `completedToolCalls` (object[]) —

- `pendingJobs` (object[]) —

- `completedJobs` (object[]) —

- `artifacts` (object[]) —

- `versionVector` (object) —
Map of clientId → logical clock counter. Used for conflict detection in multi-client sync.

- `createdAt` (string (date-time)) —

- `updatedAt` (string (date-time)) —

- `lastActiveAt` (string (date-time)) —

- `conflicts` (object[]) —
Non-empty when status is `conflict` — client must resolve before retrying

### `400` Bad Request

Invalid request

Response shape: `object`

### `401` Unauthorized

Authentication required

Response shape: `object`

### `404` Not Found

Resource not found

Response shape: `object`

**curl**

```bash
curl -X POST 'https://ivybiosciences.com/api/harness/sessions/{sessionId}/sync' \
  -H "Authorization: Bearer $IVY_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "clientId": "",
  "localVersion": 0,
  "localVector": {}
}'
```

**JavaScript**

```js
const res = await fetch('https://ivybiosciences.com/api/harness/sessions/{sessionId}/sync', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.IVY_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "clientId": "",
  "localVersion": 0,
  "localVector": {}
}),
});
const data = await res.json();
```

**Python**

```python
import os, requests

res = requests.post(
    "https://ivybiosciences.com/api/harness/sessions/{sessionId}/sync",
    headers={"Authorization": f"Bearer {os.environ['IVY_API_KEY']}"},
    json={
  "clientId": "",
  "localVersion": 0,
  "localVector": {}
},
)
data = res.json()
```
