Skip to content

Workspaces

A workspace represents one customer website inside the authenticated partner tenant. Visibility reports use the website and enabled model providers stored on the workspace.

Create or reuse a workspace

POST /v1/workspaces
Authorization: Bearer <partner-api-key>
Content-Type: application/json

Required scope: workspaces:write

Request body

Field Type Required Rules
website URL string Yes Must include http:// or https://; maximum 2,083 characters
models array or null No Model-provider selections; omit to enable every supported provider
models[].id enum Yes, inside models openai, gemini, or claude; each ID may appear only once
models[].enabled boolean Yes, inside models At least one provider must be enabled

When models is supplied, providers omitted from the array are disabled. When it is omitted or null, every currently supported provider is enabled for a new workspace. If the workspace already exists, its original model selection is returned and is not changed by the repeated request.

Example request:

curl --request POST \
  --url "$NBLICK_API_BASE_URL/v1/workspaces" \
  --header "Authorization: Bearer $NBLICK_PARTNER_API_KEY" \
  --header "Content-Type: application/json" \
  --header "X-External-Actor-Id: operator-42" \
  --data '{
    "website": "https://customer.example",
    "models": [
      {"id": "openai", "enabled": true},
      {"id": "gemini", "enabled": true},
      {"id": "claude", "enabled": false}
    ]
  }'

Response — 201 Created:

{
  "id": "pws-V1StGXR8_Z5jdHi6B-myT",
  "website": "https://customer.example/",
  "status": "active",
  "models": [
    {"id": "openai", "enabled": true},
    {"id": "gemini", "enabled": true},
    {"id": "claude", "enabled": false}
  ],
  "created_at": "2026-08-31T12:00:00Z",
  "updated_at": null
}

Both a newly created workspace and an existing workspace returned for the same canonical website use 201 Created.

Status When
201 Workspace created or existing workspace returned
401 Partner credential is missing or invalid
403 Credential lacks workspaces:write
422 Body, URL, model ID, duplicate model selection, or all-disabled selection is invalid

URL canonicalization

Equivalent spellings resolve to one workspace. The API normalizes scheme and host casing, removes a default port and URL fragment, and removes a trailing slash from a non-root path.

These values resolve to https://customer.example/:

https://customer.example
https://customer.example/
https://CUSTOMER.EXAMPLE:443/#section

Scheme, www., path, and query string remain significant. Each of these identifies a different workspace:

http://customer.example/
https://www.customer.example/
https://customer.example/es
https://customer.example/?language=es

Validation is syntactic

Workspace creation validates the URL format. Whether the website can be analyzed is reflected by the later visibility-report result.

List workspaces

GET /v1/workspaces
Authorization: Bearer <partner-api-key>

Required scope: workspaces:read

Query parameters

Parameter Type Default Rules
limit integer 50 Minimum 1, maximum 100
cursor string or null null Exact pagination.next_cursor from the preceding page
status enum or null null active or archived
created_after RFC 3339 date-time or null null Return resources created strictly after this timestamp; timezone required
created_before RFC 3339 date-time or null null Return resources created strictly before this timestamp; timezone required

Filters are combined with AND. When both date filters are supplied, created_after must be earlier than created_before. Keep the same filters while following a cursor.

Example request:

curl --get \
  --url "$NBLICK_API_BASE_URL/v1/workspaces" \
  --header "Authorization: Bearer $NBLICK_PARTNER_API_KEY" \
  --data-urlencode "status=active" \
  --data-urlencode "created_after=2026-08-01T00:00:00Z" \
  --data-urlencode "limit=50"

Response — 200 OK:

{
  "data": [
    {
      "id": "pws-V1StGXR8_Z5jdHi6B-myT",
      "website": "https://customer.example/",
      "status": "active",
      "models": [
        {"id": "openai", "enabled": true},
        {"id": "gemini", "enabled": true},
        {"id": "claude", "enabled": false}
      ],
      "created_at": "2026-08-31T12:00:00Z",
      "updated_at": null
    }
  ],
  "pagination": {
    "next_cursor": null,
    "has_more": false
  }
}

Results are ordered newest first by created_at, with id as the tie-breaker.

Status When
200 Page returned
400 Cursor is unknown, belongs to another partner, or does not match the active filters
401 Partner credential is missing or invalid
403 Credential lacks workspaces:read
422 Limit, status, timestamp, header, or date range is invalid

Retrieve a workspace

GET /v1/workspaces/{workspace_id}
Authorization: Bearer <partner-api-key>

Required scope: workspaces:read

Path parameter Type Description
workspace_id string Workspace ID returned by POST /v1/workspaces

Example request:

curl \
  --url "$NBLICK_API_BASE_URL/v1/workspaces/pws-V1StGXR8_Z5jdHi6B-myT" \
  --header "Authorization: Bearer $NBLICK_PARTNER_API_KEY"

Response — 200 OK:

{
  "id": "pws-V1StGXR8_Z5jdHi6B-myT",
  "website": "https://customer.example/",
  "status": "active",
  "models": [
    {"id": "openai", "enabled": true},
    {"id": "gemini", "enabled": true},
    {"id": "claude", "enabled": false}
  ],
  "created_at": "2026-08-31T12:00:00Z",
  "updated_at": null
}
Status When
200 Workspace returned
401 Partner credential is missing or invalid
403 Credential lacks workspaces:read
404 Workspace does not exist or belongs to another partner
422 Header validation fails

Workspace response fields

Field Type Nullable Description
id string No Opaque workspace identifier
website string No Canonical website stored for the workspace
status enum No active or archived
models array No Full provider catalog with an explicit enabled value for each provider
created_at date-time No UTC creation timestamp
updated_at date-time Yes UTC timestamp of the last change

The current API has no endpoint to update or delete a workspace or change its status or model selection. To analyze a different canonical URL, create or reuse the corresponding workspace.

After creating a workspace, use it to launch a visibility report.