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

# Signing packages and hierarchy for managers

> Create, list, cancel, and resend signing packages as a manager or admin. Also covers organizations, companies, and location endpoints.

Manager-scoped endpoints give you control over signing packages at the locations you manage, as well as read access to the organizational hierarchy (organizations → companies → locations) that underpins them. All endpoints in this group require a valid Clerk session JWT and enforce RBAC based on your signing session's module access tiers.

Access is determined by two factors: your **module tier** (from `caps.manager.signings`, `caps.manager.flows`, etc.) and your **location scope** (which locations your manager employee memberships grant access to). Admin users bypass the location scope check and instead receive global access, capped at 500 rows per list response.

Check `caps.manager` or `caps.admin` in your [session payload](/api/signing/session) before calling these routes. The relevant tiers are documented on each endpoint below.

***

## Organizations

### List organizations

Returns all organizations in your scope. Managers see only organizations they have been granted access to through their role memberships. Admins see all organizations globally, capped at 500 rows.

```
GET /v1/signing/organizations
```

<Note>
  This endpoint is at `/v1/signing/organizations` (not under `/v1/signing/manager/`). It uses the same session RBAC as other manager endpoints but is also accessible to admins.
</Note>

No query parameters.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.safeclose.com/v1/signing/organizations \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

<ResponseField name="organizations" type="array" required>
  Array of organization records in your scope.
</ResponseField>

<ResponseField name="scope" type="string" required>
  Either `"managed"` (manager, scoped to your employee memberships) or `"global"` (admin, all organizations).
</ResponseField>

#### Error responses

| Status | Condition                                                                                         |
| ------ | ------------------------------------------------------------------------------------------------- |
| `403`  | No manager or admin row is linked to your Clerk user ID (`caps.canListOrganizations` is `false`). |

***

## Companies

### List companies

Returns companies visible to you, optionally filtered by organization. Managers see only companies belonging to their accessible organizations. Admins see all companies (capped at 500).

```
GET /v1/signing/companies
```

<Note>
  This endpoint is at `/v1/signing/companies` (not under `/v1/signing/manager/`).
</Note>

<ParamField query="organizationId" type="string">
  Numeric organization ID to filter by. If you are a manager and specify an organization you do not have access to, the request returns `403`.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.safeclose.com/v1/signing/companies?organizationId=12" \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

<ResponseField name="companies" type="array" required>
  Array of company records.
</ResponseField>

<ResponseField name="scope" type="string" required>
  `"managed"` or `"global"`.
</ResponseField>

#### Error responses

| Status | Condition                                                                           |
| ------ | ----------------------------------------------------------------------------------- |
| `400`  | `organizationId` is not a valid numeric string.                                     |
| `403`  | No manager/admin identity, or the specified `organizationId` is outside your scope. |

***

### Get one company

Returns a single company record. The company must be within your accessible scope.

```
GET /v1/signing/manager/companies/:companyId
```

**Required tier:** any of `signings`, `templates`, or `flows` at `"read"` or above, or admin.

<ParamField path="companyId" type="string" required>
  Numeric company ID.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.safeclose.com/v1/signing/manager/companies/88 \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

The company record for the requested company.

#### Error responses

| Status | Condition                                                         |
| ------ | ----------------------------------------------------------------- |
| `400`  | `companyId` is not a valid numeric string.                        |
| `403`  | Insufficient module access, or the company is outside your scope. |
| `404`  | Company not found.                                                |

***

## Locations

### List locations

Returns locations under your accessible companies, optionally filtered by company. Admins receive all locations globally (capped at 500). Results are ordered by name ascending.

```
GET /v1/signing/manager/locations
```

**Required tier:** any of `signings`, `templates`, or `flows` at `"read"` or above, or admin.

<ParamField query="companyId" type="string">
  Numeric company ID to filter by. Managers specifying a company outside their scope receive `403`.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.safeclose.com/v1/signing/manager/locations?companyId=88" \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

<ResponseField name="locations" type="array" required>
  Array of location records.
</ResponseField>

<ResponseField name="scope" type="string" required>
  `"managed"` or `"global"`.
</ResponseField>

#### Error responses

| Status | Condition                                                                       |
| ------ | ------------------------------------------------------------------------------- |
| `400`  | `companyId` is not a valid numeric string.                                      |
| `403`  | Insufficient module access, or the specified `companyId` is outside your scope. |

***

### Get one location

Returns a single location record. The location's parent company must be within your scope.

```
GET /v1/signing/manager/locations/:locationId
```

**Required tier:** any of `signings`, `templates`, or `flows` at `"read"` or above, or admin.

<ParamField path="locationId" type="string" required>
  Numeric location ID.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.safeclose.com/v1/signing/manager/locations/204 \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

The location record for the requested location.

#### Error responses

| Status | Condition                                                                    |
| ------ | ---------------------------------------------------------------------------- |
| `400`  | `locationId` is not a valid numeric string.                                  |
| `403`  | Insufficient module access, or the location's company is outside your scope. |
| `404`  | Location not found.                                                          |

***

## Signing packages

### List signing packages

Returns signing packages for the locations in your scope, ordered by `updatedAt` descending. Managers can optionally filter to one location. Admins receive packages globally (capped at 500).

```
GET /v1/signing/manager/signings
```

**Required tier:** `signings` at `"read"` or above, or admin.

<ParamField query="locationId" type="string">
  Numeric location ID to filter by. Managers specifying a location outside their scope receive `403`.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.safeclose.com/v1/signing/manager/signings?locationId=204" \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

<ResponseField name="signings" type="array" required>
  Array of signing package records.
</ResponseField>

<ResponseField name="scope" type="string" required>
  `"managed"` or `"global"`.
</ResponseField>

#### Error responses

| Status | Condition                                                                         |
| ------ | --------------------------------------------------------------------------------- |
| `400`  | `locationId` is not a valid numeric string.                                       |
| `403`  | `signings` tier is `"none"`, or the specified `locationId` is outside your scope. |

***

### Get one signing package

Returns a single signing package record. The package's location must be in your scope.

```
GET /v1/signing/manager/signings/:signingId
```

**Required tier:** `signings` at `"read"` or above, or admin.

<ParamField path="signingId" type="string" required>
  Numeric signing package ID.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.safeclose.com/v1/signing/manager/signings/3001 \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

The signing package record for the requested package.

#### Error responses

| Status | Condition                                                           |
| ------ | ------------------------------------------------------------------- |
| `400`  | `signingId` is not a valid numeric string.                          |
| `403`  | Insufficient tier, or the package's location is outside your scope. |
| `404`  | Signing package not found.                                          |

***

### List documents in a package

Returns all documents in the package, ordered by `position` ascending then `id` ascending, capped at 500.

```
GET /v1/signing/manager/signings/:signingId/documents
```

**Required tier:** `signings` at `"read"` or above, or admin.

<ParamField path="signingId" type="string" required>
  Numeric signing package ID.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.safeclose.com/v1/signing/manager/signings/3001/documents \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

<ResponseField name="documents" type="array" required>
  Array of document records for this package.
</ResponseField>

#### Error responses

| Status | Condition                                                           |
| ------ | ------------------------------------------------------------------- |
| `400`  | Invalid `signingId`.                                                |
| `403`  | Insufficient tier, or the package's location is outside your scope. |
| `404`  | Signing package not found.                                          |

***

### List signers in a package

Returns the roster of signer records for the package, ordered by signer number ascending, capped at 200.

```
GET /v1/signing/manager/signings/:signingId/signers
```

**Required tier:** `signings` at `"read"` or above, or admin.

<ParamField path="signingId" type="string" required>
  Numeric signing package ID.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.safeclose.com/v1/signing/manager/signings/3001/signers \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

<ResponseField name="signers" type="array" required>
  Array of signer records for this package.
</ResponseField>

#### Error responses

| Status | Condition                                                           |
| ------ | ------------------------------------------------------------------- |
| `400`  | Invalid `signingId`.                                                |
| `403`  | Insufficient tier, or the package's location is outside your scope. |
| `404`  | Signing package not found.                                          |

***

### Create a signing package

Creates a new signing package in `draft` status at the specified location. The package has no documents or signers attached at creation time; those are added through subsequent operations.

```
POST /v1/signing/manager/signings
```

**Required tier:** `signings` at `"write"` or above, or admin.

<ParamField body="locationId" type="string" required>
  Numeric ID of the location where this package is being created. You must have access to this location.
</ParamField>

<ParamField body="flowId" type="string">
  Numeric ID of the signing flow to associate with this package. The flow must belong to the same location as `locationId`—a mismatch returns `400`.
</ParamField>

<ParamField body="note" type="string">
  A free-text note for this package. Maximum 4000 characters. Leading and trailing whitespace is trimmed before storage.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.safeclose.com/v1/signing/manager/signings \
    -H "Authorization: Bearer <clerk_jwt>" \
    -H "Content-Type: application/json" \
    -d '{
      "locationId": "204",
      "flowId": "18",
      "note": "Q3 equipment financing package for Acme Motors."
    }'
  ```
</CodeGroup>

#### Response

The newly created signing package record with `status: "draft"`.

<CodeGroup>
  ```json Example response theme={null}
  {
    "id": "3005",
    "locationId": "204",
    "flowId": "18",
    "managerId": "42",
    "status": "draft",
    "note": "Q3 equipment financing package for Acme Motors.",
    "message": null,
    "createdAt": "2025-06-15T15:00:00.000Z",
    "updatedAt": "2025-06-15T15:00:00.000Z"
  }
  ```
</CodeGroup>

#### Error responses

| Status | Condition                                                                                     |
| ------ | --------------------------------------------------------------------------------------------- |
| `400`  | Invalid body (see message), or `flowId` does not belong to the same location as `locationId`. |
| `403`  | Insufficient tier, or the specified `locationId` is outside your scope.                       |
| `404`  | `flowId` does not exist.                                                                      |

***

### Cancel a signing package

Sets the package's `status` to `"cancelled"` and optionally records a cancellation reason. The package's location must be in your scope.

```
POST /v1/signing/manager/signings/:signingId/cancel
```

**Required tier:** `signings` at `"write"` or above, or admin.

<ParamField path="signingId" type="string" required>
  Numeric signing package ID.
</ParamField>

<ParamField body="reason" type="string">
  Human-readable reason for cancellation. Maximum 2000 characters. Stored in the `message` field on the signing row. If omitted, the existing `message` value is preserved, or `"Cancelled by manager."` is set as a default.
</ParamField>

<Warning>
  If the package is already in a `cancelled` or `canceled` status, this endpoint returns `409`. Check the current `status` field before calling this endpoint if you want to avoid that error.
</Warning>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.safeclose.com/v1/signing/manager/signings/3001/cancel \
    -H "Authorization: Bearer <clerk_jwt>" \
    -H "Content-Type: application/json" \
    -d '{"reason": "Customer requested cancellation before signing."}'
  ```
</CodeGroup>

#### Response

<ResponseField name="signing" type="object" required>
  The updated signing package record with `status: "cancelled"`.
</ResponseField>

#### Error responses

| Status | Condition                                                           |
| ------ | ------------------------------------------------------------------- |
| `400`  | Invalid `signingId` or malformed request body.                      |
| `403`  | Insufficient tier, or the package's location is outside your scope. |
| `404`  | Signing package not found.                                          |
| `409`  | The package is already cancelled.                                   |

***

### Resend signing notifications

Triggers re-delivery of signer notifications for this package. The package's location must be in your scope.

```
POST /v1/signing/manager/signings/:signingId/resend
```

**Required tier:** `signings` at `"write"` or above, or admin.

<ParamField path="signingId" type="string" required>
  Numeric signing package ID.
</ParamField>

No request body.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.safeclose.com/v1/signing/manager/signings/3001/resend \
    -H "Authorization: Bearer <clerk_jwt>"
  ```
</CodeGroup>

#### Response

<ResponseField name="ok" type="boolean" required>
  `true` when the resend job was successfully enqueued.
</ResponseField>

<ResponseField name="queued" type="any">
  The result returned by the integration queue after enqueuing the job.
</ResponseField>

#### Error responses

| Status | Condition                                                           |
| ------ | ------------------------------------------------------------------- |
| `400`  | Invalid `signingId`.                                                |
| `403`  | Insufficient tier, or the package's location is outside your scope. |
| `404`  | Signing package not found.                                          |
