# Finalize signing

Archive a completed signing session as a signed PDF and send copies to the signers. Safe to retry. BankID sessions retain the original signed PDF bytes.

POST https://api.brigg.app/v1/operations/signing.FinalizeSigning

## Access & visibility

Allow `signing.FinalizeSigning` on your API key.

**Workspace access by default.** Private member data requires [approved member delegation](https://developer.brigg.app/authentication#member-delegation) through `Brigg-Act-As`; the key supplies permissions while private ownership and project boundaries remain enforced.

[Set up authentication](https://developer.brigg.app/authentication) · [Choose permissions](https://developer.brigg.app/permissions)

## Request fields

Send a JSON object with the following fields. Required fields must be included; omit optional fields you do not need.
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `signing_request_id` | string | Yes | The signing_request_id returned when signatures were requested. Read GetSigningRequest first; every recipient must have signed. At least 1 character. At most 120 characters. |

## Recover the archive after everyone has signed

The normal recipient flow triggers finalization after the last signature. This operation lets an integration retry that archive step when [Get signing request](https://developer.brigg.app/reference/signing/GetSigningRequest) reports completed but has no file_id, for example after an interrupted finalization. It never signs for a recipient or advances an incomplete request.

The call waits for the archive step. If an archive already exists, it returns that same file without creating another one or sending the copies again. Otherwise it archives the signed PDF and attempts delivery to the signers. Archive availability does not prove email delivery. A null file_id is not permission to download the original as the signed result: re-read the request.

Use [Get signing document](https://developer.brigg.app/reference/signing/GetSigningDocument) with version=signed once the archive exists. BankID preserves the collected signed PDF; it is not re-rendered. Keep the same acting identity and grants used to access this signing request.

## Follow one signing request through completion

[Upload a readable PDF](https://developer.brigg.app/files), then [request signatures](https://developer.brigg.app/reference/signing/RequestFileSignatures) and keep `signing_request_id`. The request keeps a fixed source; replacing the original file later does not change what recipients sign.

Read [Get signing request](https://developer.brigg.app/reference/signing/GetSigningRequest) for per-recipient progress. `completed` means everyone signed, but the archive can still be preparing: wait for non-null `file_id` before requesting the signed PDF. [Get signing document](https://developer.brigg.app/reference/signing/GetSigningDocument) returns a short-lived URL for either the fixed original or the signed archive.

Notification failures do not undo the signing request. Remind the affected pending recipients instead of creating a duplicate request. Recipients sign themselves; a delegated API call cannot supply a recipient's signature. See the [complete signing workflow](https://developer.brigg.app/signing).

## Response

Returns **200 OK** with a JSON body.
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `signing_request_id` | string | Yes | The same signing request, not a newly created session. |
| `status` | string | Yes | completed confirms the signing session was complete. Use file_id, not status alone, to know whether an archive is available. |
| `file_id` | string or null | Yes | Archived signed PDF identity. Use GetSigningDocument with version=signed to obtain a short-lived download URL. Null means no archive identity was returned; re-read GetSigningRequest before attempting a download. |

## Errors & retries

Set `BRIGG_REQUEST_ID` once for each logical action. The samples send it as `Idempotency-Key`. Reuse the same value and body on retries, including after a timeout; a missing response does not prove the action failed.

For rate limits, follow the server’s retry guidance and back off. See [HTTP errors](https://developer.brigg.app/http#errors) and [safe retries and limits](https://developer.brigg.app/reliability).

| HTTP status | Code | What to do |
| --- | --- | --- |
| 400 | `invalid_json` | Send a JSON object with Content-Type: application/json. |
| 400 | `invalid_input` | Check the request fields and types. Supply a stable Idempotency-Key containing 1–200 characters. |
| 401 | `invalid_key` | The workspace API key is missing, invalid or revoked. |
| 403 | `forbidden` | Check the key’s operation and resource grants. If Brigg-Act-As is supplied, the key must be authorized to delegate to that member. |
| 404 | `not_found` | The requested operation or resource is not available to this credential. |
| 429 | `rate_limited` | Wait for Retry-After before retrying. Reuse the original Idempotency-Key. |
| 409 | `not_completed` | Every recipient must finish signing first. Read GetSigningRequest; this operation cannot supply their signatures. |
| 502 | `url_scraper_failed` | Archive rendering failed. Read the signing request before retrying finalization; do not create another signing request. |

## Next steps

- [Get signing request](https://developer.brigg.app/reference/signing/GetSigningRequest)
- [Get signing document](https://developer.brigg.app/reference/signing/GetSigningDocument)
- [List signing events](https://developer.brigg.app/reference/signing/ListSigningEvents)
- [Request file signatures](https://developer.brigg.app/reference/signing/RequestFileSignatures)

[Download OpenAPI](https://developer.brigg.app/openapi.json) · [Versioning & retirement](https://developer.brigg.app/versioning)

## Examples

### The signed archive is available

A repeat returns the same archive. Download through GetSigningDocument, not a constructed storage URL.
#### cURL


```sh
curl 'https://api.brigg.app/v1/operations/signing.FinalizeSigning' \
  -H "Authorization: Bearer $BRIGG_API_KEY" \
  -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $BRIGG_REQUEST_ID" \
  --data-raw '{
  "signing_request_id": "sig_project_agreement"
}'
```

#### TypeScript


```typescript
const requestId = process.env.BRIGG_REQUEST_ID;
if (!requestId) throw new Error("Set BRIGG_REQUEST_ID once per action and reuse it on retries.");

const response = await fetch("https://api.brigg.app/v1/operations/signing.FinalizeSigning", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BRIGG_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": requestId, // Create once per action; reuse on retries.
  },
  body: JSON.stringify({
    "signing_request_id": "sig_project_agreement"
  }),
});
const result = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${result.error} — ${result.message}`);
console.log(result);
```

#### Python


```python
import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

request_id = os.environ["BRIGG_REQUEST_ID"]  # Reuse for retries of this action.
payload = {
  "signing_request_id": "sig_project_agreement"
}
request = Request(
    "https://api.brigg.app/v1/operations/signing.FinalizeSigning",
    data=json.dumps(payload).encode("utf-8"),
    headers={
        "Authorization": f"Bearer {os.environ['BRIGG_API_KEY']}",
        "Content-Type": "application/json",
        "Idempotency-Key": request_id,  # Create once per action; reuse on retries.
    },
    method="POST",
)
try:
    with urlopen(request) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))
    raise
```

#### Response example


```json
{
  "signing_request_id": "sig_project_agreement",
  "status": "completed",
  "file_id": "f_signed_agreement"
}
```

### No archive identity returned

Read GetSigningRequest again; completed describes signatures and does not replace the file_id check.
#### cURL


```sh
curl 'https://api.brigg.app/v1/operations/signing.FinalizeSigning' \
  -H "Authorization: Bearer $BRIGG_API_KEY" \
  -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $BRIGG_REQUEST_ID" \
  --data-raw '{
  "signing_request_id": "sig_project_agreement"
}'
```

#### TypeScript


```typescript
const requestId = process.env.BRIGG_REQUEST_ID;
if (!requestId) throw new Error("Set BRIGG_REQUEST_ID once per action and reuse it on retries.");

const response = await fetch("https://api.brigg.app/v1/operations/signing.FinalizeSigning", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BRIGG_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": requestId, // Create once per action; reuse on retries.
  },
  body: JSON.stringify({
    "signing_request_id": "sig_project_agreement"
  }),
});
const result = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${result.error} — ${result.message}`);
console.log(result);
```

#### Python


```python
import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

request_id = os.environ["BRIGG_REQUEST_ID"]  # Reuse for retries of this action.
payload = {
  "signing_request_id": "sig_project_agreement"
}
request = Request(
    "https://api.brigg.app/v1/operations/signing.FinalizeSigning",
    data=json.dumps(payload).encode("utf-8"),
    headers={
        "Authorization": f"Bearer {os.environ['BRIGG_API_KEY']}",
        "Content-Type": "application/json",
        "Idempotency-Key": request_id,  # Create once per action; reuse on retries.
    },
    method="POST",
)
try:
    with urlopen(request) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))
    raise
```

#### Response example


```json
{
  "signing_request_id": "sig_project_agreement",
  "status": "completed",
  "file_id": null
}
```

## JSON schemas


```json-schema-request
{
  "type": "object",
  "properties": {
    "signing_request_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120,
      "description": "The signing_request_id returned when signatures were requested. Read GetSigningRequest first; every recipient must have signed."
    }
  },
  "required": [
    "signing_request_id"
  ],
  "additionalProperties": false,
  "examples": [
    {
      "signing_request_id": "sig_project_agreement"
    }
  ]
}
```


```json-schema-response
{
  "type": "object",
  "properties": {
    "signing_request_id": {
      "type": "string",
      "description": "The same signing request, not a newly created session."
    },
    "status": {
      "type": "string",
      "description": "completed confirms the signing session was complete. Use file_id, not status alone, to know whether an archive is available."
    },
    "file_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "Archived signed PDF identity. Use GetSigningDocument with version=signed to obtain a short-lived download URL. Null means no archive identity was returned; re-read GetSigningRequest before attempting a download."
    }
  },
  "required": [
    "signing_request_id",
    "status",
    "file_id"
  ],
  "additionalProperties": false,
  "examples": [
    {
      "signing_request_id": "sig_project_agreement",
      "status": "completed",
      "file_id": "f_signed_agreement"
    }
  ]
}
```

