# GET /api/public/onboarding/progress

> Retrieve onboarding progress for the authenticated platform

- Surface: `/api/public` · operationId `getOnboardingProgress` · Group: Onboarding
- Authorisation: Token with scope `public:health:read`
- Organisation key: can't reach this route: the key check answers 403 `route_not_available`. Use a platform token for it.
- The spec: https://developers.rivr.io/openapi/api-public.json
- The spec's introduction: https://developers.rivr.io/reference/api-public.md
- Page in the portal: https://developers.rivr.io/reference/api-public/getOnboardingProgress

The examples target the sandbox (`https://api.test.rivr.io`) and need test credentials.

## Responses

### 200

OK

`application/json`

**Response fields**

| Field | Type | Description |
| --- | --- | --- |
| `completedSteps` | integer (int32) |  |
| `totalSteps` | integer (int32) |  |
| `isComplete` | boolean |  |
| `steps` | OnboardingStep[] |  |
| `steps[].stepNumber` | integer (int32) |  |
| `steps[].key` | string |  |
| `steps[].title` | string |  |
| `steps[].description` | string |  |
| `steps[].httpMethod` | string |  |
| `steps[].endpoint` | string |  |
| `steps[].isCompleted` | boolean |  |
| `steps[].completedAt` | string (date-time) | (nullable) |

**Example**

```json
{
  "completedSteps": 0,
  "totalSteps": 0,
  "isComplete": false,
  "steps": [
    {
      "stepNumber": 0,
      "key": "string",
      "title": "string",
      "description": "string",
      "httpMethod": "string",
      "endpoint": "string",
      "isCompleted": false,
      "completedAt": "2026-10-18T09:00:00Z"
    }
  ]
}
```

### 401

The token is missing (`token_missing`), not valid (`token_invalid`) or expired (`token_expired`), or it is not a
platform token (`platform_token_required`).

Error codes: [token_missing](https://developers.rivr.io/errors/token_missing.md), [token_invalid](https://developers.rivr.io/errors/token_invalid.md), [token_expired](https://developers.rivr.io/errors/token_expired.md), [platform_token_required](https://developers.rivr.io/errors/platform_token_required.md)

`application/json`

```json
{
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid Authorization Header",
  "propertyName": null,
  "message": "The request has no valid Authorization header. Send the token in the Authorization header, after Bearer.",
  "errorCode": "token_missing",
  "code": "token_missing",
  "type": "https://developers.rivr.io/errors/token_missing"
}
```

### 403

The token lacks the scope (`invalid_scope`). The body also carries `error` and `error_description`, as before.

Error codes: [invalid_scope](https://developers.rivr.io/errors/invalid_scope.md)

`application/json`

```json
{
  "error": "invalid_scope",
  "error_description": "The scope(s) 'public:health:read' is required.",
  "propertyName": null,
  "message": "The scope(s) 'public:health:read' is required.",
  "errorCode": "invalid_scope",
  "code": "invalid_scope",
  "type": "https://developers.rivr.io/errors/invalid_scope"
}
```

### 500

Something unexpected failed: `internal_error`.

Error codes: [internal_error](https://developers.rivr.io/errors/internal_error.md)

`application/json`

```json
{
  "propertyName": null,
  "message": "Something unexpected failed at Rivr, and whether the request was carried out is not known. Check the order or what the request was about before you retry.",
  "errorCode": "internal_error",
  "code": "internal_error",
  "type": "https://developers.rivr.io/errors/internal_error"
}
```

## Example request

```bash
curl -X GET https://api.test.rivr.io/api/public/onboarding/progress \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```
