> ## Documentation Index
> Fetch the complete documentation index at: https://docs.smartlyq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agency sub-accounts & SaaS

> Manage agency sub-accounts over the API, and which actions are reserved for SaaS-plan members.

If your API key's workspace is an **agency** (a whitelabel tenant), you can manage its client **sub-accounts** over the API: create them, list them, pause and resume, delete, and — for SaaS-plan members — run bulk lifecycle actions.

<Note>
  All sub-account endpoints require your key's workspace to be attached to an **agency tenant**. Other keys receive **409 `NOT_ELIGIBLE`**.
</Note>

## Two tiers of access

Basic sub-account management is available to any agency. **SaaS-mode actions are reserved for SaaS-plan members** - the tier that lets an agency bill its own clients.

| Capability           | Endpoint                                     | Requires                                  |
| -------------------- | -------------------------------------------- | ----------------------------------------- |
| Create a sub-account | `POST /v1/workspaces`                        | Agency tenant · `workspaces:write`        |
| List sub-accounts    | `GET /v1/workspaces`                         | Agency tenant · `workspaces:read`         |
| Get a sub-account    | `GET /v1/workspaces/{id}`                    | Agency tenant · `workspaces:read`         |
| Pause / resume       | `POST /v1/workspaces/{id}/pause` · `/resume` | Agency tenant · `workspaces:write`        |
| Delete               | `DELETE /v1/workspaces/{id}`                 | Agency tenant · `workspaces:write`        |
| **Disable SaaS**     | `POST /v1/workspaces/{id}/disable-saas`      | **Active SaaS plan** · `workspaces:write` |
| **Bulk lifecycle**   | `POST /v1/workspaces/bulk`                   | **Active SaaS plan** · `workspaces:bulk`  |

## SaaS-member only: SaaS actions

SaaS-mode actions — **disabling SaaS** on a sub-account and all **bulk** lifecycle actions — are **SaaS-member only**. Your agency must be on an active SaaS plan: it must have completed Stripe Connect onboarding to bill clients (the equivalent of a SaaS Pro tier).

<Note>
  This is a **stable** entitlement. Once your agency is set up for SaaS, it stays enabled even if your Stripe processor later reports a transient issue (a dispute, a review, a brief disconnect) — so you can always manage and unwind SaaS on your clients. It only turns off if you fully disconnect SaaS billing.
</Note>

<Warning>
  If your agency is not on an active SaaS plan, the SaaS endpoints (`POST /v1/workspaces/{id}/disable-saas` and `POST /v1/workspaces/bulk`) return **403 `SAAS_PLAN_REQUIRED`**. Connect a client-billing Stripe account first.
</Warning>

`POST /v1/workspaces/bulk` applies one action — `pause`, `resume`, or `disable_saas` — to up to **200** client sub-accounts at once. It requires the dedicated **`workspaces:bulk`** scope (separate from `workspaces:write`), because a mass action is high blast-radius. Because `disable_saas` is irreversible (it cancels each client's subscription and refunds each sub-wallet to the agency), it also requires a typed confirmation.

```bash theme={null}
curl -X POST https://api.smartlyq.com/v1/workspaces/bulk \
  -H "Authorization: Bearer sqk_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "workspace_ids": [101, 102, 103],
    "action": "disable_saas",
    "cancel_subscription": true,
    "confirm": "BULK"
  }'
```

The action is applied per workspace, and the response reports each outcome:

```json theme={null}
{
  "ok": true,
  "action": "disable_saas",
  "applied": 2,
  "failed": 1,
  "results": [
    { "workspace_id": 101, "ok": true,  "error": null },
    { "workspace_id": 102, "ok": true,  "error": null },
    { "workspace_id": 103, "ok": false, "error": "not_found" }
  ]
}
```

| Field             | Meaning                                              |
| ----------------- | ---------------------------------------------------- |
| `applied`         | Workspaces the action succeeded on                   |
| `failed`          | Workspaces that were skipped (see `results[].error`) |
| `results[].error` | Per-workspace failure reason (`null` on success)     |

## Not on a SaaS plan

```json theme={null}
{
  "success": false,
  "error": {
    "code": "SAAS_PLAN_REQUIRED",
    "message": "This endpoint requires an active SaaS plan: connect a Stripe account that can bill your clients before using SaaS/bulk actions."
  }
}
```

<Tip>
  Basic sub-account management (create, list, get, pause, resume, delete) stays available to every agency. Only the **SaaS-mode** actions — disable-SaaS and bulk — require an active SaaS plan. Because the gate is a stable entitlement rather than a live payment-processor check, a temporary Stripe issue never blocks you from unwinding SaaS.
</Tip>
