# Onboarding state

Source: https://docs.musicnerd.net/api-reference/onboarding/state

Onboarding state

## GET /api/onboarding/{artistId}/state

Full OpenAPI specification: https://docs.musicnerd.net/spec/onboarding.json

## Authentication

This operation's specification permits a request without authentication.

[Authentication guide](https://docs.musicnerd.net/authentication)

## Operation and referenced schemas

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Music Nerd API: onboarding",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://musicnerd-api.vercel.app",
      "description": "Production"
    },
    {
      "url": "https://musicnerd-api-staging.vercel.app",
      "description": "Staging (staging database)"
    }
  ],
  "paths": {
    "/api/onboarding/{artistId}/state": {
      "get": {
        "summary": "Onboarding state",
        "operationId": "getOnboardingState",
        "security": [],
        "description": "Where onboarding stands: confirmed steps and their confirmation times. The profile can poll this while onboarding is open. Public, uncached, and limited to step names and timestamps; it does not expose pending sources or private prepared text.\n\nAdding an artist discovers public links and Latest material while About and Lore remain private. Approving the claim does not confirm review or publication. A fresh open discovers or reuses saved profiles, then stops for explicit source review. Interview answers are optional and individually answered or skipped. About is public only after an explicit publish turn. There is no fixed completion time. An artist with no onboarding, or an unknown ID, returns every step null and currentStep profiles.",
        "parameters": [
          {
            "name": "artistId",
            "in": "path",
            "required": true,
            "description": "The artist's ID (a UUID). Staging and production IDs differ.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "aab92f80-f9e1-4299-aa33-7dd85c8de5d3"
          }
        ],
        "responses": {
          "200": {
            "description": "The artist's onboarding state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingState"
                },
                "examples": {
                  "complete": {
                    "summary": "Built (Bio Ritmo on staging)",
                    "value": {
                      "status": "ok",
                      "complete": true,
                      "currentStep": null,
                      "steps": {
                        "profiles": "2026-10-02T23:33:42.122Z",
                        "vault": "2026-10-02T23:33:46.437Z",
                        "interview": "2026-10-02T23:33:58.667Z",
                        "publish": "2026-10-02T23:33:58.667Z"
                      }
                    }
                  },
                  "building": {
                    "summary": "Mid-build: profiles and sources done, writing the About",
                    "value": {
                      "status": "ok",
                      "complete": false,
                      "currentStep": "interview",
                      "steps": {
                        "profiles": "2026-10-02T23:33:42.122Z",
                        "vault": "2026-10-02T23:33:46.437Z",
                        "interview": null,
                        "publish": null
                      }
                    }
                  },
                  "notStarted": {
                    "summary": "Not started",
                    "value": {
                      "status": "ok",
                      "complete": false,
                      "currentStep": "profiles",
                      "steps": {
                        "profiles": null,
                        "vault": null,
                        "interview": null,
                        "publish": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`artistId` isn't a UUID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "error": "Invalid artist id"
                }
              }
            }
          },
          "503": {
            "description": "The state couldn't be read. Retry; don't treat it as \"not started\".",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "error": "Onboarding state unavailable"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "OnboardingState": {
        "type": "object",
        "required": [
          "status",
          "complete",
          "currentStep",
          "steps"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok"
            ]
          },
          "complete": {
            "type": "boolean",
            "description": "True once `publish` is confirmed: the profile is built. The page stops polling here."
          },
          "currentStep": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "profiles",
              "vault",
              "interview",
              "publish",
              null
            ],
            "description": "The first step, in order, without a confirmation. `null` once all four are confirmed. `profiles` for an artist that hasn't started."
          },
          "steps": {
            "type": "object",
            "required": [
              "profiles",
              "vault",
              "interview",
              "publish"
            ],
            "description": "When each step was confirmed (ISO 8601, UTC), or `null` if it hasn't been.",
            "properties": {
              "profiles": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Profiles found and linked. The Links section can show them."
              },
              "vault": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Sources saved. The Lore section can show them."
              },
              "interview": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "The interview step, confirmed after the optional questions are answered or skipped."
              },
              "publish": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "The Lore and About written. The About can show."
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "status",
          "error"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "error"
            ]
          },
          "error": {
            "type": "string"
          }
        }
      }
    }
  }
}
```
