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¶
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/:
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¶
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¶
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.