# 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)
        }
    }
}
```


---

# Agent Instructions: 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:

```
GET https://docs.paveapi.com/hotspots/developer-docs/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
