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

# Provision Workspace (Partners)

> Create a fully configured workspace for a client and receive an API token scoped to it

Create a fully configured Penbox workspace for one of your clients, seed it with case templates, register the client's admin, and receive an API token scoped to that workspace — in a single call.

<Warning>
  This endpoint is reserved for partner integrations. A regular API token is rejected with a `401`. Talk to Penbox to have your own workspace enabled as a partner.
</Warning>

<Note>
  **The token is returned exactly once.** It appears only in the `201` response that creates the workspace, and Penbox stores nothing but its hash — it can never be retrieved again. Persist it before you do anything else with the response.
</Note>

## Idempotency

The call is idempotent on `integration.legalops.source_workspace_id`: one Penbox workspace per workspace on your side. Calling it again with the same `source_workspace_id` returns the workspace that already exists, with a `200` instead of a `201` and **without** a `token`.

Use the status code to tell the two apart:

| Status | Meaning                       | `token`       |
| ------ | ----------------------------- | ------------- |
| `201`  | The workspace was created     | Present, once |
| `200`  | The workspace already existed | Absent        |

## Partial success

Provisioning never fails halfway: if an optional step does not complete, the workspace is still created and the response carries a `warnings` array describing what was skipped — a case template that could not be copied, for instance. Log the warnings — they are not errors.


## OpenAPI

````yaml POST /workspaces
openapi: 3.0.0
info:
  title: Penbox API
  version: '1.0'
  description: >-
    The Penbox API provides programmatic access to Penbox's form management,
    case management, and document processing capabilities. Authenticate using
    Bearer tokens created at https://app.penbox.io/workspace/settings/api
servers:
  - url: https://connect.penbox.io/v1
    description: Production
  - url: https://connect.aiboov.com/v1
    description: Staging
security:
  - BearerAuth: []
paths:
  /workspaces:
    post:
      summary: Provision Workspace
      description: >-
        Create a fully configured workspace for one of your clients and return
        an API token scoped to it. Reserved for partner integrations: any other
        token is rejected with a 401.


        The call is idempotent on `integration.legalops.source_workspace_id` —
        one Penbox workspace per workspace on your side. A creation returns a
        201 carrying the token; a replay returns a 200 with the same workspace
        and no token.
      operationId: provision-workspace
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - admin
                - integration
              properties:
                name:
                  type: string
                  minLength: 3
                  maxLength: 64
                  description: >-
                    Workspace name. The slug is derived from it, with a numeric
                    suffix when that slug is already taken.
                  example: Acme Legal
                admin:
                  type: object
                  required:
                    - email
                  description: >-
                    The client's administrator. Created as a silent member:
                    Penbox never emails them.
                  properties:
                    email:
                      type: string
                      format: email
                      description: >-
                        Administrator email address. Linked to the existing
                        Penbox account when there is one.
                    given_name:
                      type: string
                      maxLength: 100
                      description: First name
                    family_name:
                      type: string
                      maxLength: 100
                      description: Last name
                    locale:
                      type: string
                      maxLength: 10
                      description: Language the administrator is addressed in
                      example: fr
                template_source:
                  type: object
                  description: Case templates to copy into the new workspace.
                  properties:
                    case_template_ids:
                      type: array
                      description: >-
                        UUIDs of the case templates to copy. A template that
                        cannot be resolved is skipped and reported in `warnings`
                        rather than failing the call.
                      items:
                        type: string
                        format: uuid
                integration:
                  type: object
                  required:
                    - legalops
                  description: >-
                    Identifies the client workspace on your side. This is what
                    makes the call idempotent.
                  properties:
                    legalops:
                      type: object
                      required:
                        - source_workspace_id
                      properties:
                        source_workspace_id:
                          type: string
                          minLength: 1
                          maxLength: 128
                          description: >-
                            Your own identifier for the client workspace, unique
                            within your partner account.
                        external_url:
                          type: string
                          format: uri
                          maxLength: 2000
                          description: HTTPS link back to the workspace in your own product
      responses:
        '200':
          description: >-
            A workspace already exists for this `source_workspace_id`. Same
            payload, without `token`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProvisionedWorkspace'
        '201':
          description: >-
            The workspace was created. This is the only response that carries
            the token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProvisionedWorkspace'
        '401':
          description: >-
            The token is not a partner token, or is not allowed to provision
            workspaces
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    ProvisionedWorkspace:
      type: object
      properties:
        replayed:
          type: boolean
          description: >-
            False when this call created the workspace, true when it returned
            one that already existed.
        workspace:
          type: object
          description: The Penbox workspace
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
            slug:
              type: string
              description: >-
                Slug derived from the name, with a numeric suffix when the slug
                was already taken
        integration:
          type: object
          description: The link back to the workspace on your side
          properties:
            legalops:
              type: object
              properties:
                status:
                  type: string
                  description: Connection status
                  example: connected
                connected_at:
                  type: string
                  format: date-time
                  description: When the workspace was connected
                source_workspace_id:
                  type: string
                  description: The identifier you sent, echoed back
                external_url:
                  type: string
                  nullable: true
                  description: The link you sent, echoed back
        token:
          type: string
          description: >-
            API token scoped to the new workspace. Returned exactly ONCE, in the
            201 that created it: Penbox stores only its hash and can never show
            it again. Absent from a replay.
          example: pnbx_0f1e2d3c4b5a69788796a5b4c3d2e1f00112233445566778
        warnings:
          type: array
          description: >-
            Optional steps that did not complete. The workspace is fully created
            either way — these are not errors. Absent when there is nothing to
            report.
          items:
            type: string
          example:
            - >-
              Template 3fa85f64-5717-4562-b3fc-2c963f66afa6 could not be
              resolved, skipped
    Error:
      type: object
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              status:
                type: string
              title:
                type: string
              detail:
                type: string
              source:
                type: object
                properties:
                  pointer:
                    type: string
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: token
      description: >-
        API token (starts with pnbx_). Create at
        https://app.penbox.io/workspace/settings/api. Include as: Authorization:
        Bearer {token}

````