---
search:
  tags:
    - Content blocks
    - PATCH
seo:
  description: >-
    Updates a user's progress (status, optional userData). userId is… Reference
    for the PATCH /content-blocks/{id}/progress/{userId} endpoint in the Fuxam
    API v4.
sidebar:
  label: Update progress for a user on a content block
  badge: PATCH
title: Update progress for a user on a content block
type: openapi-operation
---
Updates a user's progress (`status`, optional `userData`). `userId` is in the path, not the body. Scoped to your integration's institution via Basic Auth credentials.

`PATCH /content-blocks/{id}/progress/{userId}`

**Request body** (`application/json`, required)

- `status` (string) — New progress status for the user on this block
- `userData` (object) — Optional block-type-specific progress payload (e.g. survey answers, workbench state)
- `force` (boolean) — When true, bypasses some validation guards when updating status

Request body example, Mark finished with progress metadata:

```json
{
  "status": "FINISHED",
  "userData": {
    "lastViewedAt": "2026-06-23T10:15:00.000Z",
    "answers": {
      "q1": "option_a"
    }
  },
  "force": false
}
```

Request body example, Status only with empty userData:

```json
{
  "status": "IN_PROGRESS",
  "userData": {}
}
```

**Responses**

- `200` — Updated progress
- `400` — Bad Request
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found
- `429` — Too Many Requests — 1000 requests per minute per institution. Includes \`X-RateLimit-Limit\`, \`X-RateLimit-Remaining\`, \`X-RateLimit-Reset\` (ISO-8601), and \`Retry-After\` (seconds).
- `500` — Internal Server Error

Response example, 200:

```json
{
  "data": {
    "blockId": "string",
    "userId": "string",
    "status": "NOT_STARTED",
    "previousStatus": "NOT_STARTED",
    "updatedAt": "2019-08-24T14:15:22Z",
    "userData": {}
  },
  "meta": {
    "requestId": "req_1234567890_abc",
    "timestamp": "2026-06-02T07:00:00.000Z",
    "version": "v4",
    "watermark": "2019-08-24T14:15:22Z"
  }
}
```
