> For the complete documentation index, see [llms.txt](https://docs.volven.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.volven.io/api/tyr-markets-partner-api/authentication.md).

# Authentication

Every API endpoint that starts with `/volven-broker/api/` requires API key authentication.\
Every API endpoint that starts with `/volven-broker/public/` doesn't require any authentication.

#### API Key Authentication

Every request requires following authentication related HTTP headers:

* `X-API-Key`
* `X-API-Timestamp`
* `X-API-Signature`

Some requests require following business related HTTP headers:

* `X-API-User-ID`

{% hint style="danger" %}
Never share your API secret with anyone, even with TÝR Markets employees. Use it internally to sign your request. Make sure to store it securely. Stolen API secret may lead to lost funds.
{% endhint %}

#### X-API-User-ID

Some endpoints require `X-API-User-ID` header to identify the user for whom the action is executed. It can be any user that has been registered via your partner account (if you want to perform the action in the name of one of your users) or can be your partner account (if you want to perform the action as yourself). Check OpenAPI documentation for details.

{% hint style="warning" %}
If user ID is incorrect then `400 Bad Request` will be returned.

If user was not registered via you then `403 Forbidden` will be returned.
{% endhint %}

#### X-API-Key

`X-API-Key` is simply your API Key (example: `0408ad13-cd74-4e99-8fe5-9fd2badd42ec`).

{% hint style="warning" %}
If `X-API-Key` is missing or invalid then `401 Unauthorized` will be returned
{% endhint %}

#### X-API-Timestamp

`X-API-Timestamp` must be actual timestamp in Unix epoch format with millisecond precision (example: `1760721374734`). When the server receives the message it verifies if current time is same as `X-API-Timestamp` value with 5000 ms tolerance.

{% hint style="warning" %}
If `X-API-Timestamp` is missing or time drift is bigger than 5000 ms then `401 Unauthorized` will be returned
{% endhint %}

#### X-API-Signature

`X-API-Signature` is calculated in following way:

1. Prepare canonical request:  timestamp + method + path (with query string, if any) + user ID (if any) + body
2. Sign canonical request with you API Secret using HMAC SHA256 algorithm
3. Encode the signature in Base64 format.

Example:

Assume you request looks like this:

```http
POST /volven-broker/api/orders
X-API-User-ID: 789
{"orderType": "MARKET", "quoteId": "d285d287-5ab6-453b-99ed-ca1765b4231a", "side": "BUY"}
```

Canonical request would look like this:

```
1760721374734POST/volven-broker/api/orders789{"orderType": "MARKET", "quoteId": "d285d287-5ab6-453b-99ed-ca1765b4231a", "side": "BUY"}
```

Final signature would look like this:

```
wUCAlLkxQrOhOi95eheYmcL9mdHjinWvO4vTyDN+Uko=
```

{% hint style="warning" %}
If signature doesn't match then `401 Unauthorized` will be returned
{% endhint %}

#### Final request

Finally, correctly authenticated request will look like this:

```http
POST /volven-broker/api/orders
X-API-User-ID: 789
X-API-Key: 0408ad13-cd74-4e99-8fe5-9fd2badd42ec
X-API-Timestamp: 1760721374734
X-API-Signature: wUCAlLkxQrOhOi95eheYmcL9mdHjinWvO4vTyDN+Uko=
{"orderType": "MARKET", "quoteId": "d285d287-5ab6-453b-99ed-ca1765b4231a", "side": "BUY"}
```

This ensures that the server can verify the authenticity of the request by comparing the received signature with its own calculation. By using these elements — `X-API-Key`, `X-API-Timestamp`, and `X-API-Signature` — your API requests will be secure from replay attacks while maintaining data integrity.

#### Postman authentication script

If you want to quickly test the API before implementing authentication you may use following pre-request script in Postman (make sure to define `API_KEY` , `API_SECRET` and `API_USER_ID` environment variables):

```javascript
(async () => {
    const apiKey = pm.environment.get("API_KEY");
    const secretBase64 = pm.environment.get("API_SECRET"); // Base64-encoded secret key
    const apiUserId = pm.environment.get("API_USER_ID");

    if (!apiKey || !secretBase64) {
        console.error("Missing api_key or api_secret in environment");
        return;
    }

    // Unix timestamp in milliseconds
    const timestamp = Date.now();

    // Construct canonical string
    const method = pm.request.method.toUpperCase();
    const pathWithQuery = pm.request.url.getPathWithQuery();
    const userId = apiUserId ?? "";
    const rawBody = pm.request.body?.raw ?? "";
    const body = pm.variables.replaceIn(rawBody);
    const canonicalRequest = timestamp + method + pathWithQuery + userId + body;

    // Base64 <-> ArrayBuffer helpers
    const base64ToArrayBuffer = (base64) => {
        const binary = atob(base64);
        const len = binary.length;
        const bytes = new Uint8Array(len);
        for (let i = 0; i < len; i++) bytes[i] = binary.charCodeAt(i);
        return bytes.buffer;
    };
    const arrayBufferToBase64 = (buffer) => {
        let binary = "";
        const bytes = new Uint8Array(buffer);
        for (let i = 0; i < bytes.byteLength; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return btoa(binary);
    };

    // Generate HMAC-SHA256 signature
    const keyBuffer = base64ToArrayBuffer(secretBase64);
    const cryptoKey = await crypto.subtle.importKey(
        "raw",
        keyBuffer,
        { name: "HMAC", hash: "SHA-256" },
        false,
        ["sign"]
    );
    const sigBuffer = await crypto.subtle.sign("HMAC", cryptoKey, new TextEncoder().encode(canonicalRequest));
    const signatureBase64 = arrayBufferToBase64(sigBuffer);

    // Set authentication headers
    pm.request.headers.upsert({ key: "X-API-Key", value: apiKey });
    pm.request.headers.upsert({ key: "X-API-Timestamp", value: timestamp.toString() });
    pm.request.headers.upsert({ key: "X-API-Signature", value: signatureBase64 });
    pm.request.headers.upsert({ key: "X-API-User-ID", value: apiUserId });

    console.log("Canonical:", canonicalRequest);
    console.log("Signature:", signatureBase64);
    console.log("Timestamp:", timestamp);
})();
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.volven.io/api/tyr-markets-partner-api/authentication.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
