# Authentication

### Introduction

This section provides the details on how to use the `curl` command to access the PAVE OpenAPI sessions endpoint using `API-Key`, `API-Token`, and `API-Timestamp` headers. The `API-Key` and `API-Token` are used for authentication purposes, and the `API-Timestamp` is used for ensuring the freshness of the request.

### Endpoint

```bash
https://openapi.paveapi.com/v1/sessions
```

### HMAC-SHA256

HMAC (Keyed-Hash Message Authentication Code) is a cryptographic technique that calculates a message authentication code by combining a cryptographic hash function with a secret key. In the case of the PAVE Capture API, the cryptographic hash function used is SHA256, resulting in the algorithm known as HMAC-SHA256.

### Prerequisites

* A valid API Key and API Token should be obtained before accessing the API endpoint.
* `curl` must be installed on your system.

### Steps to Use curl

1. Open a terminal or command prompt.
2. Use the following `curl` command to access the API endpoint:

```bash
curl -H "API-Key: <Your_API_Key>" \
     -H "API-Token: <Your_Generated_Access_Token>" \
     -H "API-Timestamp: <UTC_Datetime_String>" \
     https://openapi.paveapi.com/v1/sessions
```

3. Replace `<Your_API_Key>` with your API Key.
4. Replace `<Your_Generated_Access_Token>` with your API Token.
5. Replace `<UTC_Datetime_String>` with the UTC datetime in the format `YYYY-MM-DDTHH:MM:SSZ`. For example, `2023-02-11T12:00:00Z`.
6. Execute the `curl` command.
7. The API endpoint will return a JSON object containing the session data.

### Headers

The following headers are required for each API request:

| Header Name     | Description                                                                         |
| --------------- | ----------------------------------------------------------------------------------- |
| `API-Key`       | Your API Key, which is used to identify your account and provide access to the API. |
| `API-Token`     | A generated access token, which is used to authenticate your API request.           |
| `API-Timestamp` | The UTC datetime string, which is used to verify the freshness of your request.     |

### Note

* Make sure to replace the placeholders with the actual values before executing the `curl` command.
* Ensure that the UTC datetime string in the `API-Timestamp` header is accurate and up-to-date, as it is used for ensuring the freshness of the request.
* `API-Token`: will expire within 5 minutes.

### Response

If the request is successful, the API server will return a JSON object that contains the session information, including the session ID, expiration time, and the associated API Key and access token.

Example response:

```json
{
  "session_id": "f8f4e4c1-6416-4d4a-8b16-f15a4e4a1c2d",
  "expiration": "2023-02-11T12:00:00Z",
  "api_key": "abcd1234",
  "api_token": "efgh5678"
}
```

### Error Responses

If there is an error with the request, the API server will return a JSON object with an error message. Some possible error messages include:

* `Invalid API Key`: The provided API Key is invalid or does not match any existing accounts.
* `Invalid API Token`: The provided access token is invalid or has expired.
* `Invalid API Timestamp`: The provided UTC datetime string is invalid or the request is stale.

Example error response: **`403 Forbidden`**&#x20;

```json
 {
  "message": "Unable to validate the request, please recheck your API-Key and API-Token."
}
```

### Here are examples of how to make this API request using different programming languages:

#### JavaScript

```javascript
const axios = require('axios');

const apiKey = '<Your_API_Key>';
const apiToken = '<Your_Generated_Access_Token>';
const apiTimestamp = '<UTC_Datetime_String>';

axios({
  method: 'post',
  url: 'https://openapi.paveapi.com/v1/sessions',
  headers: {
    'API-Key': apiKey,
    'API-Token': apiToken,
    'API-Timestamp': apiTimestamp
  }
})
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error.response.data);
  });
```

#### Python

```python
import requests

api_key = '<Your_API_Key>'
api_token = '<Your_Generated_Access_Token>'
api_timestamp = '<UTC_Datetime_String>'

headers = {
    'API-Key': api_key,
    'API-Token': api_token,
    'API-Timestamp': api_timestamp
}

response = requests.post(
    'https://openapi.paveapi.com/v1/sessions',
    headers=headers
)

if response.status_code == 200:
    print(response.json())
else:
    print(response.json()['error'])
```

#### Go

```go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

const apiKey = "<Your_API_Key>"
const apiToken = "<Your_Generated_Access_Token>"
const apiTimestamp = "<UTC_Datetime_String>"

func main() {
	url := "https://openapi.paveapi.com/v1/sessions"

	client := &http.Client{}
	req, err := http.NewRequest("POST", url, nil)
	if err != nil {
		fmt.Println(err)
		return
	}

	req.Header.Set("API-Key", apiKey)
	req.Header.Set("API-Token", apiToken)
	req.Header.Set("API-Timestamp", apiTimestamp)

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return
	}

	defer resp.Body.Close()

	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)

	fmt.Println(result)
}
```

#### Swift

```swift
import Foundation

let apiKey = "your_api_key"
let apiToken = "your_generated_access_token"
let url = URL(string: "https://openapi.paveapi.com/v1/sessions")!
let timestamp = DateFormatter().string(from: Date())

var request = URLRequest(url: url)
request.addValue(apiKey, forHTTPHeaderField: "API-Key")
request.addValue(apiToken, forHTTPHeaderField: "API-Token")
request.addValue(timestamp, forHTTPHeaderField: "API-Timestamp")

let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
    guard let data = data, let response = response as? HTTPURLResponse, error == nil else {
        print("Error: \(error?.localizedDescription ?? "Unknown error")")
        return
    }

    if response.statusCode == 200 {
        print(String(data: data, encoding: .utf8) ?? "Empty response")
    } else {
        print("Unexpected response code: \(response.statusCode)")
        print(String(data: data, encoding: .utf8) ?? "Empty response")
    }
}
task.resume()

```

#### Kotlin

```kotlin
import java.net.URL
import javax.net.ssl.HttpsURLConnection

fun main() {
    val apiKey = "<Your_API_Key>"
    val apiToken = "<Your_Generated_Access_Token>"
    val apiTimestamp = "<UTC_Datetime_String>"

    val url = URL("https://openapi.paveapi.com/v1/sessions")

    with(url.openConnection() as HttpsURLConnection) {
        requestMethod = "POST"
        setRequestProperty("API-Key", apiKey)
        setRequestProperty("API-Token", apiToken)
        setRequestProperty("API-Timestamp", apiTimestamp)

        inputStream.bufferedReader().use {
            val response = it.readText()
            println(response)
        }
    }
}
```
