# Calculate the HTTP message signature

## Signature parameters and signature input

The Investment API uses a strict configuration of the [HTTP message signatures calculation algorithm](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-15) and requires particular request components to be included in the signature
calculation process.

The request signature is transported via two HTTP headers that must be present in all API requests, `signature-input` and `@signature-params`.  This page describes how these headers are generated.

See also: [Signature Components and Metadata](/products/byol/concepts/api_concepts/http_signatures/v15/v15_signature_components) for descriptions of how inputs to this process are created.

## How to calculate the signature

After all signature components are defined along with the [`@signature-params` component](/products/byol/concepts/api_concepts/http_signatures/v15/v15_signature_components#metadata-of-the-signature-params-component), the following signature header values can be calculated.

### Signature header values

| Header name | Description | Format |
|  --- | --- | --- |
| `signature-input` | This HTTP header is a dictionary structured field [RFC 8941](https://datatracker.ietf.org/doc/html/rfc8941). It contains the metadata for the HTTP message signature generated from the [listed components](/products/byol/concepts/api_concepts/http_signatures/v15/v15_signature_components) of the HTTP message (which are [defined in the IETF draft for HTTP message signatures](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-15#name-the-signature-input-http-fi)). | `sig1={signature params value}`  `{signature params value}` is equal to the value of the component `@signature-params`. |


**Example signature input**


```http
signature-input: sig1=("@method" "@path" "@query" "accept" "authorization" "content-length" "content-type" "content-digest" "idempotency-key" "upvest-client-id");keyid="8d4997a8-cf7a-4e51-adbb-401656a3e5c2";created=1633529659;expires=1633529664;nonce="o085M4cMgpbicuOL"
```

| Header name | Description | Format |
|  --- | --- | --- |
| `signature` | This HTTP header is a dictionary structured field [RFC 8941](https://datatracker.ietf.org/doc/html/rfc8941). It contains one message signature generated from the [listed components](/products/byol/concepts/api_concepts/http_signatures/v15/v15_signature_components) of the HTTP message (which are [defined in the IETF draft for HTTP message signatures](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-15#name-the-signature-http-field)). The signature value is enclosed by colons (`:`). | `sig1=:{signature value}:`  `{signature value}` is equal to the calculated signature value. |


If you'd like more information about these HTTP headers, please follow the links in this table.

| Header name | Description | Documentation |
|  --- | --- | --- |
| `signature-input` | Metadata for a message signature generated from components within the HTTP message | [Link](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-15#name-the-signature-input-http-fi) |
| `@signature-params` | Metadata defining which parameters are included in the calculation of the signature | [Link](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-15#signature-params) |
| `signature` | Message signature generated from components within the HTTP message | [Link](https://datatracker.ietf.org/dochtml/draft-ietf-httpbis-message-signatures-15#name-the-signature-http-field) |


## Calculating the signature value

To calculate the signature value, proceed as follows:

Take all signature components in the same order as the component keys listed in `@signature-params`.


Append the `@signature-params` component to the end of this list (even though it is not explicitly listed as a signature component in `@signature-params` itself).


Merge them using the new line character (`\n`, i.e. ASCII 0x0a) as a delimiter.

**Example signature base string**


```http
"@method": POST
"@path": /endpoint
"@query": ?a=b
"accept": application/json
"authorization": Bearer the-OAuth2-access-token-goes-here
"content-length": 16
"content-type": application/json
"content-digest": sha-512=:Hd9/AvGZkbjitW1+Ml8Fg1ux1mtcDYe6mLQjDyoowIWa3LM/PmwN2v9O+MjtQGrCA3EQWUL54dlgxKHyYbrucw==:
"idempotency-key": 424e8603-f12c-4a58-8eb1-5edfe471f3ab
"upvest-client-id": 5ec16164-6173-461d-b90d-116d68f55b40
"@signature-params": ("@method" "@path" "@query" "accept" "authorization" "content-length" "content-type" "content-digest" "idempotency-key" "upvest-client-id");keyid="8d4997a8-cf7a-4e51-adbb-401656a3e5c2";created=1633529659;expires=1633529664;nonce="o085M4cMgpbicuOL"
```

Calculate the signature using the signing key and then encode the resulting signature by using [Base64 encoding](https://datatracker.ietf.org/doc/html/rfc4648).


The signature base string must not contain any terminating, leading, or additional spaces or line breaks.

**Example signature header**


```http
signature: sig1=:MIGIAkIBwgt8M6z9WDdEoUOh/2c5zIQxKHfQalVKjepSGibcG2JD0PJ9FYOD65aq8L2FotNcDvWliJKFrdEwZNJCgMVrx7MCQgG8cMJ3dorHLDwmJpp93CdBRMujBWvIpL+dcVawRpzKXt6ZTNkuPLrHKOkKYRtVRyPrnBuG5T9A71VMGUOJFeo3oA==:
```