# Initiate Sign Request

This endpoint allows RP to initiate a signing session by sending the raw PDF document. The service processes the document to set up a signing transaction and returns a unique sign request identifier along with a signing URL to redirect users to in order for them to perform the signing.

## Implementation Notes

1. Each signing session allows for **one user** to affix **up to 20 signatures** within **one PDF document.**
2. RPs may optionally **specify the intended signer** by providing their NRIC
   1. If specified, only this individual will be able to view and sign the document
   2. If left blank, the document will be "locked" to the first user who accesses it, and no other users will be able to access or sign it. If another user needs to access the document instead, RPs must initiate a new signing session.&#x20;
3. All signing sessions must be initiated via the [Singpass button](https://docs.sign.singpass.gov.sg/ux-guidelines#implementing-the-sign-with-singpass-button) and not through providing any redirect links directly to the user.&#x20;

<figure><img src="https://372330916-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXnljQgt54HuOtH3cKCRP%2Fuploads%2F3EsQcQVa9OiMWvcjfIvl%2Fimage.png?alt=media&#x26;token=25c57113-0bb9-4a8a-b197-721ed6ad5ccb" alt=""><figcaption><p>Sign with Singpass button</p></figcaption></figure>

3. Each signing session has a validity of **30 mins**. RPs should only initiate a request when the application is ready to redirect the user to the Sign portal to perform the signing.

## **Path**

&#x20;<mark style="color:green;">`POST`</mark> `/sign-requests`

## **Headers**

| Name          | Value                      |
| ------------- | -------------------------- |
| Content-Type  | `application/octet-stream` |
| Authorization | `<token>`                  |

## **Authorization token**

RPs should sign the signature parameter into a JWT token as authorization token.&#x20;

**Token Type:** Standard JWT ([JSON Web Token](https://datatracker.ietf.org/doc/html/rfc7519))

{% hint style="info" %}
You can use the free tool <https://jwt.io/> to verify if your token is signed properly.&#x20;
{% endhint %}

RPs should specify the payload based on whether they require one or multiple signatures from the user. RPs can also increase the security of the signing session by specifying the identity of the individual who can view and sign the document using the `signer_uin_hash` field.&#x20;

**Note:** Multiple signatures will still only be performed by *one* user. If you require multiple *different* users to sign the same document, you must iteratively start a new signing session with the signed output of the previous user's signing session.

{% tabs %}
{% tab title="Single Signature" %}
**Use Case:** If you only require the user to sign on one location within the document.

**Payload:**

* `x` & `y`: Coordinates for placing the signature. The values should be ≥ 0 and <1, with a maximum precision of four decimal places. See detailed explanation in [#how-to-set-signing-coordinates](#how-to-set-signing-coordinates "mention")
* `page`: The page number for placing the signature. Starting from 1.&#x20;
* `doc_name`: The name of the document. This will be shown to the user.
* `client_id`: Your application's registered client ID.
* `signer_uin_hash` : (Optional) A SHA256 hash of the user's NRIC in uppercase. If specified, only this user will be able to view and sign the document. Refer to [#negative-flows](https://docs.sign.singpass.gov.sg/for-relying-parties/api-documentation/sign-portal#negative-flows "mention") for error flows your user might see after logging in.
* `jti`: Standard JWT ID, a unique identifier for the JWT, must be a UUID.
* `iat` & `exp`: Standard Issued At / Expiration timestamp of JWT. Must issued within 2 minutes.

**Example:**

{% code overflow="wrap" %}

```
eyJhbGciOiJFUzI1NiIsImtpZCI6ImQ5YmUyYzU5LThlN2QtNGJiMS1iZTcwLTA4YWExMTcxNWI0ZiJ9.eyJjbGllbnRfaWQiOiI5UmdHQ0hlOFgxIiwiZG9jX25hbWUiOiJ0ZXN0LnBkZiIsIngiOjEsInkiOjEsInBhZ2UiOjEsImlhdCI6MTc0NzM3NzQ5MiwianRpIjoiZWEzOTI3ZGMtNmUxNy00YzkyLWJjZmUtNjU3NTE4NTg5YWM2In0.Hibgb47lL9cXpRzH0hjSRg027bZHBSY5lsGXH9MKukHyDbUi4d6hMcTVu_xYF6dJXPizFmRceuxaQVKM_h1pYA
```

{% endcode %}
{% endtab %}

{% tab title="Multiple Signatures" %}
**Use Case:** If you require the same user to sign on multiple locations within the same document.&#x20;

**Payload:**

* `sign_locations` : an array of up to 20 signature locations. Each location is an object containing `x` ,`y` , and `page` .  See detailed explanation in [#how-to-set-signing-coordinates](#how-to-set-signing-coordinates "mention")
* `doc_name`: The name of the document. This will be shown to the user.
* `client_id`: Your application's registered client ID.
* `signer_uin_hash` : (Optional) A SHA256 hash of the user's NRIC in uppercase. If specified, only this user will be able to view and sign the document. Refer to [#negative-login-flows](https://docs.sign.singpass.gov.sg/for-relying-parties/api-documentation/sign-portal#negative-login-flows "mention") for error flows your user might see after logging in.
* `jti`: Standard JWT ID, a unique identifier for the JWT, must be a UUID.
* `iat` & `exp`: Standard Issued At / Expiration timestamp of JWT. Must issued within 2 minutes.

{% hint style="warning" %}
Please note that we will reject the request if there are overlapping signatures detected.
{% endhint %}

**Example:**&#x20;

{% code overflow="wrap" %}

```
eyJhbGciOiJFUzI1NiIsImtpZCI6InBUaHpVbl9JNVJXZzcyQWEyUzI1LXhoRG0wRzBNWjNSN3FpWUdyYmVmT0EifQ.eyJkb2NfbmFtZSI6ImR1bW15LnBkZiIsImNsaWVudF9pZCI6IkF3UkRhX01Jd1NnR3JYdXJTX2U0N3NtVXptSG5LVF9ZIiwianRpIjoiOGVhMGYwYjAtYThkMi00ODEyLWI5ZjktZDczYzQwNDY2NjIxIiwic2lnbl9sb2NhdGlvbnMiOlt7IngiOjAsInkiOjAsInBhZ2UiOjF9LHsieCI6MC41LCJ5IjowLjUsInBhZ2UiOjF9XSwiaWF0IjoxNzU4MDA2ODY2LCJleHAiOjE3NTgwMDY5ODZ9.L0QeAhmZHGdb0C2ywMkwslFwUCC-g5XuqMLiiBNAX9c5kuaDcWqJNkhohfqv4SGJLa_9CHZtLD7DCTiMxiJvoQ
```

{% endcode %}
{% endtab %}
{% endtabs %}

## **Body**

Raw binary PDF content

### PDF Requirements

* PDF must be less than 10 MB in size.
* PDF must have less than 100 pages.
* PDF must be unencrypted.
* PDF must not be a hybrid-reference PDF
  * for example, this can happen if you export a PDF from Word using the option **“Best for electronic distribution and accessibility.”**
* If the PDF contains existing signature(s):
  * These signatures should fulfil the requirements of a PAdES signature (minimally B-T). \
    \&#xNAN;*Note: Signatures created with Sign will automatically fulfil these requirements*&#x20;
  * These signatures should not overlap with the x-y coordinates given.
* The dimension allowed for each page are as follows:
  * Minimum width: 220pt or 300px
  * Minimum height: 60pt or 80px
  * Maximum width and height: 3370pt or 4490px
  * Ratio between width and height must be less than 2. e.g. 300px x 1000px document will not be accepted, even though it is within the acceptable range of width and height.

### Privacy

The PDF document is held temporarily during the signing process and purged when no longer needed.

## **Sample request**

```sh
curl 'https://staging.sign.singpass.gov.sg/api/v3/sign-requests' \
  -H 'authorization: XXX' \
  -H 'content-type: application/octet-stream' \
  --data 'file=@path_to_your_test.pdf'
```

## **Response**

{% tabs %}
{% tab title="Created (201)" %}
The signing URL will bring the signer to the [Sign Portal](https://docs.sign.singpass.gov.sg/for-relying-parties/api-documentation/sign-v3/sign-portal) where they will perform the signing.&#x20;

```json
{
  "request_id": "signv3-01961944-5491-785a-baf2-edea694ae61a",
  "signing_url": "https://staging.sign.singpass.gov.sg/?token=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InNpZ24tc3RnLTAxIn0.eyJyZXF1ZXN0X2lkIjoic2lnbnYzLTAxOTYxOTQ0LTU0OTEtNzg1YS1iYWYyLWVkZWE2OTRhZTYxYSIsImlhdCI6MTc0NDE4MDYzMCwiZXhwIjoxNzQ0MTgyNDMwfQ.UGBmPO2IHUKxyMO9ZjpGt_NuhHqbBTz2IuFmYcHFzi0slw3K1V-XpIfVqW8ua3PGoWf52jNPBH2lkPhcz69r6A",
  "exchange_code": "37994734-1d76-4d27-b5f0-96dd1504cf67"
}
```

{% hint style="info" %}
`signing_url` will only be valid for **30 minutes** upon issuance. RPs are expected to create sign requests on demand upon signing.&#x20;

We may change the format of`signing_url` at any point of time.
{% endhint %}

{% hint style="warning" %}
`exchange_code` should be treated as a secret as it will be used to [get the signing result](https://docs.sign.singpass.gov.sg/for-relying-parties/api-documentation/sign-v3/get-signing-result). Please **do not** share the code or put in your application logs.
{% endhint %}
{% endtab %}

{% tab title="Invalid File Error (400)" %}
There may be a few scenarios under which you will receive a 400 error:

* `CONTENT_TOO_LARGE`: File size has exceeded 10 MB
* `BAD_SIGN_LOCATION`: The signature coordinates could be out of bounds, overlapping other forms or in a page that is non existent.
* `INVALID_PDF`: The PDF file in the request may be corrupted or set with MDP permissions that restrict further signing.
* `CLIENT_SIDE_ERROR`: A catch-all error for bad input values (for e.g. a number when a string is expected)

```json
{
  "error": "BAD_SIGN_LOCATION",
  "error_description": "Signature field is out of bounds",
  "id": "ca21bb57-8255-46f0-b2f4-80613768ea6e",
  "trace_id": "7755321139078968799"
}
```

{% endtab %}

{% tab title="Auth Token Error (401)" %}

```json
{
  "error": "UNAUTHORIZED",
  "error_description": "Unauthorized.",
  "error_details": "JWT validation failed",
  "id": "ca21bb57-8255-46f0-b2f4-80613768ea6e",
  "trace_id": "7755321139078968799"
}
```

{% endtab %}

{% tab title="Server error (500)" %}

```json
{
  "error": "SERVER_SIDE_ERROR",
  "error_description": "Something went wrong.",
  "id": "ca21bb57-8255-46f0-b2f4-80613768ea6e",
  "trace_id": "7755321139078968799"
}
```

{% endtab %}
{% endtabs %}

## How to set signing coordinates

When starting a sign request, define the signature position using the `x` and `y` parameters in the JWT payload. These coordinates are percentage-based and relative to the PDF's dimensions, starting from the bottom left corner.

* **y**: Vertical position (0 to 1), where 0 is the bottom and 1 is the top.
* **x**: Horizontal position (0 to 1), where 0 is the left and 1 is the right.

We will not accept coordinates where a signature cannot be placed due to being outside the page boundaries. The **signature size is fixed at 60x225 points**, regardless of the PDF size.

| Example                                                                                                                                                                                                                                                     |                                                                                                                                                                                                                                                                                                        |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <p>✅ <strong>x = 0, y =  0</strong></p><p></p><p>The bottom-left corner of the signature is positioned at the bottom-left corner of the document.</p>                                                                                                       | <img src="https://372330916-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXnljQgt54HuOtH3cKCRP%2Fuploads%2F2jwM68VquK9Djp7QO5TE%2FAcrobat%202025-04-09%2015.25.51.png?alt=media&#x26;token=5b54bf7c-15d4-4648-9d1f-e20a09a7ccf0" alt="" data-size="original">                    |
| <p>✅ <strong>x = 0.5, y = 0.5</strong></p><p>The bottom-left corner of the signature is positioned in the center of the document.</p>                                                                                                                       | <img src="https://372330916-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXnljQgt54HuOtH3cKCRP%2Fuploads%2F4V93B7srW2BaZBjPzRje%2FTP%20Screenshot%202025-04-09%20at%2015.28.20%402x.png?alt=media&#x26;token=184e7fa5-1b17-4692-9fa8-9ac55b490c1b" alt="" data-size="original">  |
| <p>🚫 <strong>x = 1, y = 1</strong></p><p>Error: Signature will be out of page area</p>                                                                                                                                                                     |                                                                                                                                                                                                                                                                                                        |
| <p>🚫 <strong>x = 0.00001, y = 0.00001</strong></p><p>Error: Coordinates can only be specified up to 4 decimal places. </p>                                                                                                                                 |                                                                                                                                                                                                                                                                                                        |
| <p>⚠️ <strong>x = 0, y = 0</strong><br>Signature will appear cropped if the PDF has been set to a coordinate other than (0,0). This is usually not the default behaviour for PDFs, and you can check this at Page Box / Media box settings of your PDF.</p> | <img src="https://372330916-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXnljQgt54HuOtH3cKCRP%2Fuploads%2FJeMvPOI2wa1I9szSp6vW%2FScreenshot%202025-09-02%20at%2010.23.57%E2%80%AFAM.png?alt=media&#x26;token=1d08ba48-0cbb-41a3-ae97-f1cd59a84d3b" alt="" data-size="original"> |
