Site Members & Access

Site members are the people who sign in to your site — not the people who sign in to SpiderPublish to build it. They live in their own store, and a site member never becomes a dashboard user, never joins your workspace and never appears in your team list.

This page documents the 23 endpoints behind the Members area of the dashboard: members themselves, member groups, per-page access, data restrictions and single sign-on.

Authentication

Every route on this page accepts either a bearer project token or a dashboard session cookie. The bearer form is the one you want from a script or an agent:

https://spideriq.ai/api/v1/dashboard/...
Authorization: Bearer $PROJECT_TOKEN

$PROJECT_TOKEN is either a client_id:api_key:api_secret triplet or a PAT. Send no token and you get a 401.

There is no members command in the CLI and no members_* tool in the MCP server. This REST API is the agent surface for the feature.

Scoping

Member operations resolve against a project — the site whose members you are managing. A bearer token resolves its own project; a dashboard session resolves the project you have selected. If neither yields one, every route returns 400 with A project must be selected to manage site members.

Two routes additionally need a client scope (GET /dashboard/members/quota and POST /dashboard/members/invite); without one they return 400 with A client scope is required.

Errors common to every route

These apply to all 23 endpoints and are not repeated in full below.

Status

When

Resolution

401

no Authorization header, or a token that does not resolve

send Authorization: Bearer $PROJECT_TOKEN; a malformed triplet also returns 401, not 400

400

no project could be resolved

select a project in the dashboard, or use a token scoped to one

404

the path does not exist

check the path — a good token on a bogus path returns 404, which is how you tell a routing typo from an auth problem

502

the members service did not answer

Members service unavailable. Transient; retry. It is not a validation failure and the request was not applied

422

a body field failed validation

the response names the field and the constraint


Members

GET /dashboard/members

List the site's members.

Parameters

Name

Type

Required

Description

search

string

no

free-text filter, ≤200 chars

limit

integer

no

page size, 1–200, default 50

offset

integer

no

rows to skip, ≥0, default 0

Example

curl "https://spideriq.ai/api/v1/dashboard/members?limit=50" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response200

{ "members": [], "total": 0 }

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

GET /dashboard/members/quota

Report whether the plan allows another member, and where the count currently sits.

Parameters — none.

Example

curl "https://spideriq.ai/api/v1/dashboard/members/quota" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response200. limit is null when the plan sets no ceiling.

{ "allowed": true, "limit": null, "current": 0 }

Errors:

Status

When

Resolution

400

no client scope resolved

A client scope is required — use a token scoped to a client

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

POST /dashboard/members/invite

Create a member and, when you supply the site's own login URL, email them an invitation.

Parameters

Name

Type

Required

Description

email

string

yes

3–254 chars; must contain @ and a dot in the domain

name

string

no

≤200 chars

role

string

no

≤64 chars

groups

string[]

no

up to 50 group slugs

site_name

string

no

≤200 chars; used in the invitation email

login_url

string

no

≤2048 chars. Must be your own site's login page. Omit it and the member is created but no email is sent

Example

curl -X POST "https://spideriq.ai/api/v1/dashboard/members/invite" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "email": "ada@example.com",
        "name": "Ada Lovelace",
        "groups": ["members"],
        "site_name": "Ada'\''s Club",
        "login_url": "https://club.example.com/login"
      }'

Response201. The created member, plus emailed telling you whether an invitation actually went out.

{ "id": "...", "email": "ada@example.com", "status": "invited", "emailed": true }

Errors:

Status

When

Resolution

409

the plan's member limit is reached

the message carries current/limit; raise the plan or remove a member

422

email failed shape validation

must contain @ and a dot in the domain part

400

no client scope resolved

A client scope is required

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

POST /dashboard/members/{user_id}/ban

Ban a member. Because a member's token lives at most fifteen minutes, a ban takes effect within one token lifetime rather than instantly.

Parametersuser_id (path, required): the member's id.

Example

curl -X POST "https://spideriq.ai/api/v1/dashboard/members/usr_123/ban" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response200

{ "ok": true }

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

POST /dashboard/members/{user_id}/unban

Restore a banned member and set the role they come back with.

Parameters

Name

Type

Required

Description

user_id

string (path)

yes

the member's id

role

string (body)

no

1–64 chars, default member

Example

curl -X POST "https://spideriq.ai/api/v1/dashboard/members/usr_123/unban" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role": "member"}'

Response200

{ "ok": true }

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

POST /dashboard/members/{user_id}/role

Set a member's role.

Parameters

Name

Type

Required

Description

user_id

string (path)

yes

the member's id

role

string (body)

yes

1–64 chars

Example

curl -X POST "https://spideriq.ai/api/v1/dashboard/members/usr_123/role" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role": "editor"}'

Response200

{ "ok": true }

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

PATCH /dashboard/members/{user_id}

Update a member's status or group membership. Send only what you are changing.

Parameters

Name

Type

Required

Description

user_id

string (path)

yes

the member's id

status

string

no

one of active, invited, banned

groups

string[]

no

up to 50 group slugs; replaces the member's set

Example

curl -X PATCH "https://spideriq.ai/api/v1/dashboard/members/usr_123" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"groups": ["members", "beta"]}'

Response200

{ "ok": true }

Errors:

Status

When

Resolution

400

neither status nor groups supplied

Nothing to update — send at least one field

422

status is not one of the three allowed values

use active, invited or banned

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied


Member groups

A group is how you name which members get through. Two groups are built in and cannot be edited or deleted: visitors and logged_in.

GET /dashboard/member-groups

List the project's groups, built-in ones included.

Parameters — none.

Example

curl "https://spideriq.ai/api/v1/dashboard/member-groups" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response200

{
  "groups": [
    { "slug": "visitors",  "name": "Visitors",        "builtin": true, "membership_type": "builtin" },
    { "slug": "logged_in", "name": "Logged-in users", "builtin": true, "membership_type": "builtin" }
  ]
}

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

POST /dashboard/member-groups

Create a group. membership_type decides whether you maintain the list yourself or let a predicate decide.

Parameters

Name

Type

Required

Description

slug

string

yes

1–64 chars, the stable key you reference from page access and restrictions

name

string

yes

1–200 chars, the display name

membership_type

string

no

≤16 chars, default manual

condition_predicate

object

no

the rule evaluated at check time for a dynamic group

Example

curl -X POST "https://spideriq.ai/api/v1/dashboard/member-groups" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"slug": "members", "name": "Paying members", "membership_type": "manual"}'

Response201, the created group.

Errors:

Status

When

Resolution

409

the slug is already taken on this project

pick another slug, or patch the existing group

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

PATCH /dashboard/member-groups/{group_id}

Rename a group, activate or deactivate it, or change its predicate.

Parameters

Name

Type

Required

Description

group_id

string (path)

yes

the group's id

name

string

no

1–200 chars

active

boolean

no

deactivate without deleting

condition_predicate

object

no

replaces the rule

clear_predicate

boolean

no

default false; set true to remove the rule and make the group manual again

Example

curl -X PATCH "https://spideriq.ai/api/v1/dashboard/member-groups/grp_123" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Founding members", "active": true}'

Response200, the updated group.

Errors:

Status

When

Resolution

404

Group not found

check the id; built-in groups are not patchable

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

502

Members service unavailable

transient; retry — the request was not applied

DELETE /dashboard/member-groups/{group_id}

Delete a group.

Parametersgroup_id (path, required).

Example

curl -X DELETE "https://spideriq.ai/api/v1/dashboard/member-groups/grp_123" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response204, no body.

Errors:

Status

When

Resolution

404

Group not found

check the id; built-in groups cannot be deleted

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

502

Members service unavailable

transient; retry — the request was not applied


Page access

Access is enforced at the edge, before the page is rendered. Every page is public until you say otherwise — turning members on does not gate anything you have not gated yourself.

GET /dashboard/pages/{page_id}/access

Read one page's access setting.

Parameterspage_id (path, required).

Example

curl "https://spideriq.ai/api/v1/dashboard/pages/23daf8be-8d91-458c-a33a-4eabcaba24b2/access" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response200

{ "access": "public", "allowed_groups": [] }

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

PUT /dashboard/pages/{page_id}/access

Set one page's access level.

Parameters

Name

Type

Required

Description

page_id

string (path)

yes

the page's id

access

string

yes

≤32 chars — public, a signed-in requirement, or a group restriction

allowed_groups

string[]

no

up to 100 group slugs; the groups that may read the page

Example

curl -X PUT "https://spideriq.ai/api/v1/dashboard/pages/23daf8be-8d91-458c-a33a-4eabcaba24b2/access" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"access": "group", "allowed_groups": ["members"]}'

Response200, the stored access record.

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied


Data restrictions

Gating a page is not enough on its own: a component on a public page can still fetch content you meant to keep back. A data restriction closes that gap for blog posts.

Version one is deliberately narrow. Only source_id: "posts" with field: "tag" and op: "in" is honoured at read time. Rows with any other field or op are stored and ignored — they will not filter anything. This is not yet a general record-level filter.

The rule is deny by default: once posts carry any restriction, nothing is visible except what a rule allows, and a member sees the union of what all their groups allow.

GET /dashboard/data-restrictions

List the project's restrictions.

Parameters — none.

Example

curl "https://spideriq.ai/api/v1/dashboard/data-restrictions" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response200

{ "restrictions": [] }

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

POST /dashboard/data-restrictions

Create a restriction: this group may see posts carrying these tags.

Parameters

Name

Type

Required

Description

source_id

string

yes

1–128 chars. Only posts is honoured today

group_slug

string

yes

1–64 chars, the group the rule applies to

field

string

yes

1–64 chars. Only tag is honoured today

op

string

no

≤16 chars, default in. Only in is honoured today

allowed_values

string[]

no

up to 500 values, each ≤256 chars — the tags this group may see

Example

curl -X POST "https://spideriq.ai/api/v1/dashboard/data-restrictions" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "source_id": "posts",
        "group_slug": "members",
        "field": "tag",
        "op": "in",
        "allowed_values": ["members-only", "archive"]
      }'

Response201, the created restriction.

Errors:

Status

When

Resolution

422

an entry in allowed_values is over 256 chars

shorten it; the response names the constraint

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

PATCH /dashboard/data-restrictions/{restriction_id}

Change a restriction's operator, values, or active state.

Parameters

Name

Type

Required

Description

restriction_id

string (path)

yes

the restriction's id

op

string

no

≤16 chars

allowed_values

string[]

no

up to 500 values; replaces the list

active

boolean

no

disable without deleting

Example

curl -X PATCH "https://spideriq.ai/api/v1/dashboard/data-restrictions/res_123" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"allowed_values": ["members-only"]}'

Response200, the updated restriction.

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

DELETE /dashboard/data-restrictions/{restriction_id}

Delete a restriction. Remember deny-by-default: removing the last rule on a source makes that source unrestricted again.

Parametersrestriction_id (path, required).

Example

curl -X DELETE "https://spideriq.ai/api/v1/dashboard/data-restrictions/res_123" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response204, no body.

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied


Single sign-on

Members can always sign in with an email and password, a magic link or a one-time code. SSO adds an identity provider you register yourself. Google is available at the platform level; per-project providers are OIDC.

GET /dashboard/sso-config

Read the project's just-in-time provisioning policy — what happens the first time somebody signs in through a provider.

Parameters — none.

Example

curl "https://spideriq.ai/api/v1/dashboard/sso-config" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response200. auto_provision: false is the default, which means SSO is invite-gated.

{ "auto_provision": false, "default_role": "member", "default_groups": [] }

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

PUT /dashboard/sso-config

Set the provisioning policy. An omitted field is left unchanged, so you can send one key.

Parameters

Name

Type

Required

Description

auto_provision

boolean

no

true creates a member on first SSO sign-in; false keeps it invite-only

default_role

string

no

1–64 chars, the role a provisioned member gets

default_groups

string[]

no

up to 50 slugs, each ≤64 chars

Example

curl -X PUT "https://spideriq.ai/api/v1/dashboard/sso-config" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"auto_provision": true, "default_role": "member", "default_groups": ["staff"]}'

Response200, the stored policy.

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

GET /dashboard/sso-providers

List the project's identity providers. Client secrets are never returned.

Parameters — none.

Example

curl "https://spideriq.ai/api/v1/dashboard/sso-providers" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response200

{ "providers": [] }

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

GET /dashboard/sso-providers/{provider_id}

Read one provider, enriched with the callback URLs to register at the identity provider's end.

Parametersprovider_id (path, required).

Example

curl "https://spideriq.ai/api/v1/dashboard/sso-providers/okta" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response200. Includes the callback URLs derived from your verified domains; client_secret is omitted.

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

PUT /dashboard/sso-providers/{provider_id}

Create or replace a provider. This is an upsert, and client_secret is required on every save — the config is stored as one blob and the secret is never returned, so a save without it would erase it.

Parameters

Name

Type

Required

Description

provider_id

string (path)

yes

your key for this provider

issuer

string

yes

8–2048 chars, must start with https://

domain

string

yes

1–253 chars, the email domain routed to this provider

client_id

string

yes

1–256 chars

client_secret

string

yes

1–1024 chars, required on every save

discovery_endpoint

string

no

≤2048 chars

scopes

string[]

no

up to 20

pkce

boolean

no

mapping

object

no

claim-to-field mapping

Example

curl -X PUT "https://spideriq.ai/api/v1/dashboard/sso-providers/okta" \
  -H "Authorization: Bearer $PROJECT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "issuer": "https://example.okta.com",
        "domain": "example.com",
        "client_id": "0oa1b2c3",
        "client_secret": "'"$OKTA_SECRET"'",
        "scopes": ["openid", "email", "profile"],
        "pkce": true
      }'

Response200, the stored provider plus its callback URLs. client_secret is not echoed.

Errors:

Status

When

Resolution

422

issuer is not an https:// URL

plain http and bare hostnames are rejected

422

client_secret missing

it is required on every save, not only the first

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

DELETE /dashboard/sso-providers/{provider_id}

Remove a provider. Members who signed in through it keep their accounts; they can no longer use that route to sign in.

Parametersprovider_id (path, required).

Example

curl -X DELETE "https://spideriq.ai/api/v1/dashboard/sso-providers/okta" \
  -H "Authorization: Bearer $PROJECT_TOKEN"

Response204, no body.

Errors:

Status

When

Resolution

401

no or invalid Authorization header

send Authorization: Bearer $PROJECT_TOKEN

400

no project could be resolved

select a project, or use a project-scoped token

404

the path does not exist

check the path — a good token on a bogus path returns 404

502

Members service unavailable

transient; retry — the request was not applied

Publish