# Welcome to Fivemerr

Cloud Storage for your gaming server. A simple and secure way to store and share your game server files.

### About Fivemerr

Fivemerr was created by MonkeyWhisper, owner of [Project Sloth](https://discord.gg/projectsloth) and [1 of 1 Servers](https://www.1of1servers.com/), in response to the lack of CDN services for FiveM images, videos, and sounds. While initially designed for FiveM, our API can be integrated with almost any platform or games.

### Why is this free?

We believe in giving back to the community that has supported and encouraged us to work on various projects. Project Sloth embodies this spirit of giving back, and Fivemerr is another way for us to show our gratitude.

### How are you able to offer this?

Fivemerr operates on hardware owned by [1 of 1 Servers](https://www.1of1servers.com/). Since we own all the hardware, we can provide this service for free thanks to our infrastructure.

### Where are the Terms of Service and Privacy Policy?

We use the 1 of 1 Servers Terms of Service and Privacy Policy, which can be found [here.](https://www.1of1servers.com/terms)

## Important Information:

* **Account Inactivity**: If your account is inactive for 60 days, it will be deleted and terminated without notice to free up space for others.
* **Zero Usage**: Accounts with 0 GB usage will be deleted within 7 days to free up space for others.
* **Storage Requests**: Once you reach 20 GB of storage, you can request additional space via a ticket at no extra charge, subject to availability and account review.
* **Resource Abuse**: Do not abuse our resources, or your account will be terminated immediately without notice.
* API Keys: You are prohibited from sharing them with anyone except for your own personal use and your own resources. Sharing API keys will result in immediate account termination without notice.


# Setup

To access the API, you need to create an API token by signing up for an account at Fivemerr.

1. Sign up at Fivemerr and login to your account.
2. Navigate to the "API Tokens" page in the dashboard.
3. Click the "Create token" button.
4. Choose a token type.
5. Click on "Create" button.
6. Copy the API Token.

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2FbeN8axOD7fvgaG0aDYQR%2Fimage.png?alt=media&amp;token=3dbb1727-1c60-4997-b751-259664508bbb" alt=""><figcaption><p>Token Creation Dialog</p></figcaption></figure>


# Images

To upload an image to the Image API, send a POST request to the API endpoint.

## API Endpoint

URL: <https://api.fivemerr.com/v1/media/images>

## Authorization

You can access the API using one of the following methods:

* Include the `Authorization` header with your API key.
* Include the `apiKey` as a query parameter in the URL.

## Supported Request Formats

The API supports the following request formats:

* form-data
* json
* x-www-form-urlencoded

Each request must include the appropriate header to be accepted.

## Form Data Requests

### Body

The request body should be a form-data object containing a file named `file` or `data`.&#x20;

### Response

The response JSON body takes the following shape:

```json
{
    "id": 3,
    "uuid": "f1ce38a5-4e05-456e-9e86-33c2f269fcdf",
    "filename": "f1ce38a5-4e05-456e-9e86-33c2f269fcdf.jpg",
    "original_filename": "xjss8mp8il3b1.jpg",
    "mime_type": "image/jpeg",
    "size": 180585, // in bytes
    "hash": "63b89ee6f0b2e368d9823c5c0fc42b4ad080b42548c8d692516ea6a942ab612f",
    "url": "https://fivermerr/files/images/f1ce38a5-4e05-456e-9e86-33c2f269fcdf.jpg",
    "created_at": "2024-07-04T00:53:53.569154676+05:30",
    "updated_at": "2024-07-04T00:53:53.569154745+05:30"
}
```

### Example with Node.js (with Axios)

```javascript
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');

// Load the image file
const filePath = '/path/to/your/image.png'; // Replace with your file path
const file = fs.createReadStream(filePath);

// Create a form data object
const form = new FormData();
form.append('file', file);

// Make the POST request
axios.post('https://api.fivemerr.com/v1/media/images', form, {
  headers: {
    ...form.getHeaders(),
    'Authorization': 'YOUR_API_KEY' // Replace with your API key
  }
})
.then(response => {
  console.log(response.data.url);
})
.catch(error => {
  console.error(error);
});

```

### Example with Python

```python
import requests

# Load the image file
file_path = '/mnt/data/image.png' # Replace with your file path
files = {'file': open(file_path, 'rb')}

# Set the headers
headers = {
    'Authorization': 'YOUR_API_KEY', # Replace with your API key
    'Content-Type': 'multipart/form-data'
}

# Make the POST request
response = requests.post('https://api.fivemerr.com/v1/media/images', files=files, headers=headers)

# Print the response
print(response.json())
```

## JSON Requests

### Body

The request body should be a JSON string containing a key named `file` or `data`.  Data should be encoded as base64 in the following format.

```
data:[<mediatype>][;base64],<data>
```

### Example with Node.js (with Axios)

<pre class="language-javascript"><code class="lang-javascript"><strong>const axios = require('axios');
</strong>
let data = JSON.stringify({
  "file": "data:image/png;base64,iVBORw0KGgoAAA=="
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://api.fivemerr.com/v1/media/images',
  headers: { 
    'Content-Type': 'application/json', 
    'Authorization': '••••••'
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});
</code></pre>

## x-www-form-urlencoded Requests

### Body

The request body should be x-www-form-urlencoded containing a key named `file` or `data`.  Data should be encoded as base64 in the following format.

```
data:[<mediatype>][;base64],<data>
```

### Example with Node.js (with Axios)

```javascript
const axios = require('axios');
const qs = require('qs');
let data = qs.stringify({
  'file': 'data:image/png;base64,iVBORw0kJggg==' 
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://api.fivemerr.com/v1/media/images',
  headers: { 
    'Content-Type': 'application/x-www-form-urlencoded', 
    'Authorization': '••••••'
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});
```

## Supported Image Extensions&#x20;

If you need any other added, let us know.

* **JPEG** - `.jpeg`
* **PNG** - `.png`
* **WEBP**- `.webp`
* **GIF** - `.gif`
* **BMP** - `.bmp`
* **TIFF** - `.tif` or `.tiff`
* **HEIC** - `.heic`
* **SVG** - `.svg`
* **ICO** - `.ico`

## FiveM Integration&#x20;


# Audio

To upload an audio to the Audio API, send a POST request to the API endpoint.

## API Endpoint

URL: <https://api.fivemerr.com/v1/media/audios>

## Authorization

You can access the API using one of the following methods:

* Include the `Authorization` header with your API key.
* Include the `apiKey` as a query parameter in the URL.

## Supported Request Formats

The API supports the following request formats:

* form-data
* json
* x-www-form-urlencoded

Each request must include the appropriate header to be accepted.

## Form Data Requests

### Body

The request body should be a form-data object containing a file named `file` or `data`.&#x20;

### Response

The response JSON body takes the following shape:

```json
{
    "id": 1,
    "uuid": "54812bad-eb9a-4ad0-bf90-412185a27e74",
    "filename": "54812bad-eb9a-4ad0-bf90-412185a27e74.mp3",
    "original_filename": "joe_japanese.mp3",
    "mime_type": "audio/mpeg",
    "size": 307722,
    "hash": "4dfdfa634076d6f6abf3b84486c7c2940c1a8d86e60535c4aaca2692fbb6d650",
    "url": "https://fivemerr.com/files/audios/54812bad-eb9a-4ad0-bf90-412185a27e74.mp3",
    "created_at": "2024-07-04T01:04:27.772178312+05:30",
    "updated_at": "2024-07-04T01:04:27.772178364+05:30"
}
```

### Example with Node.js (with Axios)

```javascript
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');

// Load the image file
const filePath = '/path/to/your/audio.mp3'; // Replace with your file path
const file = fs.createReadStream(filePath);

// Create a form data object
const form = new FormData();
form.append('file', file);

// Make the POST request
axios.post('https://api.fivemerr.com/v1/media/audios', form, {
  headers: {
    ...form.getHeaders(),
    'Authorization': 'YOUR_API_KEY' // Replace with your API key
  }
})
.then(response => {
  console.log(response.data.url);
})
.catch(error => {
  console.error(error);
});

```

### Example with Python

```python
import requests

# Load the image file
file_path = '/mnt/data/image.mp3' # Replace with your file path
files = {'file': open(file_path, 'rb')}

# Set the headers
headers = {
    'Authorization': 'YOUR_API_KEY', # Replace with your API key
    'Content-Type': 'multipart/form-data'
}

# Make the POST request
response = requests.post('https://api.fivemerr.com/v1/media/audios', files=files, headers=headers)

# Print the response
print(response.json())

```

## JSON Requests

### Body

The request body should be a JSON string containing a key named `file` or `data`.  Data should be encoded as base64 in the following format.

```
data:[<mediatype>][;base64],<data>
```

### Example with Node.js (with Axios)

<pre class="language-javascript"><code class="lang-javascript"><strong>const axios = require('axios');
</strong>
let data = JSON.stringify({
  "file": "data:image/png;base64,iVBORw0KGgoAAA=="
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://api.fivemerr.com/v1/media/audios',
  headers: { 
    'Content-Type': 'application/json', 
    'Authorization': '••••••'
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});
</code></pre>

## x-www-form-urlencoded Requests

### Body

The request body should be x-www-form-urlencoded containing a key named `file` or `data`.  Data should be encoded as base64 in the following format.

```
data:[<mediatype>][;base64],<data>
```

### Example with Node.js (with Axios)

```javascript
const axios = require('axios');
const qs = require('qs');
let data = qs.stringify({
  'file': 'data:image/png;base64,iVBORw0kJggg==' 
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://api.fivemerr.com/v1/media/audios',
  headers: { 
    'Content-Type': 'application/x-www-form-urlencoded', 
    'Authorization': '••••••'
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});
```

## Supported Audio Types

If you need any other added, let us know.

* **MPEG** - `.mpeg`\
  Files with the extension .mp1, .mp2, .mp3 must use audio/mpeg mimetype. audio/mp3 doesn't exist as such, it is a common mime type but it's official approach is to use the audio/mpeg.
  * **MP4**- `.mp3`
  * **MP3**- `.mp4`
* **WAV** - `.wav`
* **OGG** - `.ogg`
* **AAC** - `.aac`
* **FLAC** - `.flac`
* **WMA** - `.wma`
* **AIFF** - `.aiff` or `.aif`
* **PCM** - `.pcm`
* **AMR** - `.amr`


# Video

To upload a video to the Video API, send a POST request to the API endpoint.

## API Endpoint

URL: <https://api.fivemerr.com/v1/media/videos>

## Authorization

You can access the API using one of the following methods:

* Include the `Authorization` header with your API key.
* Include the `apiKey` as a query parameter in the URL.

## Supported Request Formats

The API supports the following request formats:

* form-data
* json
* x-www-form-urlencoded

Each request must include the appropriate header to be accepted.

## Form Data Requests

### Body

The request body should be a form-data object containing a file named `file` or `data`.&#x20;

### Response

The response JSON body takes the following shape:

```json
{
    "id": 1,
    "uuid": "acdde24a-1a46-4880-9744-8b26b49f0460",
    "filename": "acdde24a-1a46-4880-9744-8b26b49f0460.mp4",
    "original_filename": "input.mp4",
    "mime_type": "video/mp4",
    "size": 137489,
    "hash": "ee828a888bf2c429b878306f8fc35bf9a7daff097b48a5cb7909a033f53274ed",
    "url": "https://fivemerr.com/files/videos/acdde24a-1a46-4880-9744-8b26b49f0460.mp4",
    "created_at": "2024-07-04T01:06:59.245622227+05:30",
    "updated_at": "2024-07-04T01:06:59.245622285+05:30"
}
```

### Example with Node.js (with Axios)

```javascript
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');

// Load the image file
const filePath = '/path/to/your/video.mp4'; // Replace with your file path
const file = fs.createReadStream(filePath);

// Create a form data object
const form = new FormData();
form.append('file', file);

// Make the POST request
axios.post('https://api.fivemerr.com/v1/media/videos', form, {
  headers: {
    ...form.getHeaders(),
    'Authorization': 'YOUR_API_KEY' // Replace with your API key
  }
})
.then(response => {
  console.log(response.data.url);
})
.catch(error => {
  console.error(error);
});

```

### Example with Python

```python
import requests

# Load the image file
file_path = '/mnt/data/video.mp4' # Replace with your file path
files = {'file': open(file_path, 'rb')}

# Set the headers
headers = {
    'Authorization': 'YOUR_API_KEY', # Replace with your API key
    'Content-Type': 'multipart/form-data'
}

# Make the POST request
response = requests.post('https://api.fivemerr.com/v1/media/videos', files=files, headers=headers)

# Print the response
print(response.json())
```

## JSON Requests

### Body

The request body should be a JSON string containing a key named `file` or `data`.  Data should be encoded as base64 in the following format.

```
data:[<mediatype>][;base64],<data>
```

### Example with Node.js (with Axios)

<pre class="language-javascript"><code class="lang-javascript"><strong>const axios = require('axios');
</strong>
let data = JSON.stringify({
  "file": "data:image/png;base64,iVBORw0KGgoAAA=="
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://api.fivemerr.com/v1/media/videos',
  headers: { 
    'Content-Type': 'application/json', 
    'Authorization': '••••••'
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});
</code></pre>

## x-www-form-urlencoded Requests

### Body

The request body should be x-www-form-urlencoded containing a key named `file` or `data`.  Data should be encoded as base64 in the following format.

```
data:[<mediatype>][;base64],<data>
```

### Example with Node.js (with Axios)

```javascript
const axios = require('axios');
const qs = require('qs');
let data = qs.stringify({
  'file': 'data:image/png;base64,iVBORw0kJggg==' 
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://api.fivemerr.com/v1/media/videos',
  headers: { 
    'Content-Type': 'application/x-www-form-urlencoded', 
    'Authorization': '••••••'
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});
```

## Supported Video Type

If you need any other added, let us know.

* **MP4** - `.mp4`
* **OGG** - `.ogg`
* **WEBM** - `.webm`
* **AVI** - `.avi`
* **MKV** - `.mkv`
* **MOV** - `.mov`
* **WMV** - `.wmv`
* **FLV** - `.flv`
* **M4V** - `.m4v`


# Logs

To create a log using the Logs API, send a POST request to the API endpoint.

## API Endpoint

URL: [https://api.fivemerr.com/v1/logs](< https://api.fivemerr.com/v1/logs>)

## Authorization

You can access the API using one of the following methods:

* Include the `Authorization` header with your API key.
* Include the `apiKey` as a query parameter in the URL.

## Body

The request body should be a JSON object containing the following keys:

* **level** (required): A string. Recommended values include:
  * `info`
  * `warn`
  * `error`
  * `fatal`
  * `debug`
* **message** (required): A string.
* **resource** (optional): A string.
* **metadata** (optional): A JSON object of any shape.

### **Example**

```json5
{
    "level": "fatal",
    "message": "Something went wrong in the server",
    "resource": "core",
    "metadata": {
        "server": "Primary",
        "team": "unknown"
    }
}
```

## Example with Node.js (with Axios)

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

const data = {
    "level": "fatal",
    "message": "Something went wrong in the server",
    "resource": "core", // optional
    "metadata": { // optional
        "server": "Primary",
        "team": "unknown"
    }
}

const config = {
  method: 'post',
  url: 'https://api.fivemerr.com/v1/logs',
  headers: { 
    'Content-Type': 'application/json', 
    'Authorization': '••••••'
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(response.data);
})
.catch((error) => {
  console.log(error);
});

```


# DB Backups

Follow the instructions below to backup your database. You need to gather your details for your database and server details. \
\
Backups for all regular members are every 4 days and have a max of 2 backups all together.&#x20;

## Backup Settings

{% hint style="success" %}

#### Name:

Enter a memorable name for your reference, such as the name of your RP server.

#### MySQL Host:

This is the IP address of the server where your database is hosted (where XAMPP or MySQL is installed).

#### MySQL Port:

The default port is usually 3306, but you may have a custom port. You need to open this port in your firewall to allow the connection. For instructions on how to open your ports, you can visit [this](https://docs.1of1servers.com/1-of-1-knowledge-base/opening-your-ports) article. Ensure you open port 3306 for TCP incoming only.

\
**IMPORTANT:** **DO NOT** open your ports without adding a password to your database, as this will allow anyone to log into your database.
{% endhint %}

{% hint style="success" %}
MySQL Database:\
To find the name of your database, you can use a database viewer such as HeidiSQL. Refer to the example below for guidance. If you are using this for FiveM, you can typically find the database name in your `server.cfg` file.

![](https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2F3DQSoPnHVh6LwM6YirRI%2Fimage.png?alt=media\&token=e6d5695b-ebb3-4772-ab97-e9a159eef378)\
\
MySQL User:\
You can typically find the MySQL user in the `mysql_connection_string` section of your FiveM `server.cfg` file. By default, it is usually set to `root` unless it has been changed.
{% endhint %}

{% hint style="danger" %}
MySQL Password: \
If it is currently unset (no password), you need to set a password for security reasons.

**IMPORTANT:** **DO NOT** open your ports without adding a password to your database, as it will allow anyone to log into your database.

To add a password to your database, open your database command prompt and run the following command, replacing `MyNewPasswordGoesHere` with the password you want to set:

```sql
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPasswordGoesHere');
FLUSH PRIVILEGES;

```

After setting a password, you need to configure your database to allow connections from outside your local machine. Open your database command prompt and run the following command, replacing `MyPasswordGoesHere` with your database password:

```sql
CREATE USER 'root'@'%' IDENTIFIED BY 'MyPasswordGoesHere';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
```

\
If this is for FiveM, your `server.cfg` should then be updated to include the following line with your new password and your database name.

```sql
set mysql_connection_string "mysql://root:MyNewPasswordGoesHere@localhost/YourDataBaseNameHere?charset=utf8mb4"
```

{% endhint %}

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2FVrnrYV2EnBYygrfQ0Sxa%2Fimage.png?alt=media&amp;token=f5add3df-a487-4f8c-8954-f82acb83b1e9" alt=""><figcaption></figcaption></figure>


# Media

Description coming soon...


# API Tokens

Description coming soon...


# Servers

Description coming soon...


# Logs

Description coming soon...


# Webhooks

Description coming soon...


# screenshot-basic

Every server comes with this already if you do not have it, download the resource from [here.](https://github.com/citizenfx/screenshot-basic)

Use the following export.

```lua
exports['screenshot-basic']:requestScreenshotUpload('https://api.fivemerr.com/v1/media/images', 'file', {
    headers = {
        Authorization = 'YOUR_API_KEY'
    },
    encoding = 'png'
}, function(data)
    local resp = json.decode(data)
    local link = (resp and resp.url) or 'invalid_url'
    print(link)
end)
```


# ShareX

This will allow you to utilize ShareX to automatically upload your screenshots from ShareX to Fivemerr. This will also copy the URL to your clipboard to automatically paste where you choose.

## Configuration

* Open ShareX main application
* Open Destinations > Custom Uploader Settings
* Create New Uploader
* Set name to Fivemerr
* Request URL: <https://api.fivemerr.com/v1/media/images> (Must be typed in)
* Header Name: Authorization
* Value: Your\_Api\_Key (Add your API Key here)
* File Form Name: file
* URL {json:url}
* Change destination to Custom Image Uploader

**Please see attached images to see a detailed outline of how it should look**

<figure><img src="https://files.fivemerr.com/images/b95e2338-caf4-4867-bb1e-48f8d83981f8.png" alt=""><figcaption><p>Custom Uploader Settings</p></figcaption></figure>

<figure><img src="https://files.fivemerr.com/images/7aa68d84-4fff-4c19-a415-8db1ad935d8d.png" alt=""><figcaption><p>Image Uploader Settings</p></figcaption></figure>

<figure><img src="https://files.fivemerr.com/images/e2ff6b4b-e006-4d33-a74a-852792763bcc.png" alt=""><figcaption><p>After Capture Tasks Settings</p></figcaption></figure>


# Logs


# fm-logs

Stripped apart from JD\_Logsv3 Discord and converted to Fivemerr API log support.

🤓 FiveM Logger by Fivemerr

A logging resource for your FiveM server that logs directly to [Fivemerr's](https://fivemerr.com/) api.

## Download

[GitHub](https://github.com/FiveMerr/fm-logs)

## Readme

[Readme](https://github.com/FiveMerr/fm-logs/blob/main/README.md)

## Requirements

* FXServer With at least build: `5562`
* [screenshot-basic](https://github.com/citizenfx/screenshot-basic)

## Installation

* Add your Fivemer Logs API Key in `server.cfg` here `set fivemerr:apiToken "token"`.
* Configure your framework or standalone on `shared > config.lua` line 8.

## Features

* Chat Logs
* Join Logs
* Spawn Logs (Based on specified framework)
* Leave Logs
* Damage Logs
* Death Logs
* Weapon Logs
* Resource Logs
* Explosion Logs
* TxAdmin Logs
* Screenshot Logs

## Preview

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2FbZ6KOgPq9uOPf7q8alE4%2Fimage.png?alt=media&amp;token=88db7305-7008-417e-8420-d8deb0ae1a5d" alt=""><figcaption></figcaption></figure>

## Custom Logging

You may use `fm-logs` to leverage custom reporting to Fivemerr by using the following export function:

```
-- Example of a createLog function
exports['fm-logs']:createLog({
    LogType = "Player", -- The log type, must be defined in Config.Logs
    Message = "Player action here", -- The message of the log
    Level = "info", -- The level of the log (can be filtered on Fivemerr) (info by default)
    Resource = "script-name", -- Resource where the log is coming from (If not provided, `fm-logs` will be set by default)
    Source = 1, -- Server id for player (Required for Player Attributes to be pulled)
    Metadata = {} -- Custom attributes to be added
})
```

The export can be used on both server and client sides.

## Framework Support

This logger does not require a framework, however, if you use QBCore or ESX, you can set these in the config to display the player's character name in the logs on Fivemerr. Setting a framework will also enable the "playerConnected" log in the spawn logs as it will listen to the player loaded event based on the framework specified.

```
Framework = "qb", -- "qb" | "esx" | "standalone"
```

If you do not use a framework, simply set this to "standalone".

## Credits

* [iratetech](https://github.com/ir8scripts)
* [JD\_logsV3](https://github.com/JohnnyS/JD_logsV3)


# ox\_logs

Download the snippet here [Fivemerr's OX LIB](https://github.com/ItsTrapson/ox_lib-fivemerr)

Thanks to trapson for the snippet.

Add the below snippet on:

```
ox_lib\imports\logger\server.lua
```

```lua
if service == 'fivemerr' then
    local key = GetConvar('fivemerr:key', '')

    if key ~= '' then
        local endpoint = 'https://api.fivemerr.com/v1/logs'

        local headers = {
            ['Authorization'] = key,
            ['Content-Type'] = 'application/json',
            ['User-Agent'] = 'ox_lib'
        }

        function lib.logger(source, event, message, ...)
            if not buffer then
                buffer = {}

                SetTimeout(500, function()
                    PerformHttpRequest(endpoint, function(status, _, _, response)
                        if status ~= 200 then 
                            if type(response) == 'string' then
                                response = json.decode(response) or response
                                badResponse(endpoint, status, response)
                            end
                        end
                    end, 'POST', json.encode(buffer), headers)

                    buffer = nil
                end)
            end

            buffer = {
                level = "info",
                message = event .. " - " .. message,
                resource = cache.resource,
                metadata = {
                    event = event,
                    playerid = source,
                    tags = formatTags(source, ... and string.strjoin(',', string.tostringall(...)) or nil),
                }
            }
        end
    end
end
```

Add this to your server.cfg with your Logs API KEY.

```
set ox:logger "fivemerr"
# Get the key from API Tokens on Fivemerr Panel
set fivemerr:key "API KEY HERE"
# Logging via ox_lib (0: Disable, 1: Standard, 2: Include AddItem/RemoveItem, and all shop purchases)
set inventory:loglevel 2
```

Preview:

<figure><img src="https://images-ext-1.discordapp.net/external/2tkDnEhasKWqVLqXZmdXj0scEb4ZEg84Pgj9DjJnDu4/https/trapson.pictures/images/png/GKmaN.png?format=webp&#x26;quality=lossless" alt=""><figcaption></figcaption></figure>


# qb-logs

Download and use. [fm-logs.](https://github.com/FiveMerr/fm-logs)

We now support `qb-logs` without having to alter `qb-smallresources` directly. To enable this, set the following configuration variable values:

```
Config.Framework = "qb"
Config.Logs.Framework = true
```


# Phone Scripts


# QBCore Phone

Every standard QB-Core server comes with `screenshot-basic` and `qb-phone` out of the box. This at present is configured to use Discord as a CDN.

To *upgrade* to Fivemerr, follow these simple instructions below:

## Server File Change

* Navigate to `qb-phone/main/server/main.lua`
* Update `WebHook` to the Fivemerr API url based on your token type.
  * Missed the Fivemerr setup? You can find it [here](https://docs.fivemerr.com/introduction-to-api/readme)

```lua
local WebHook = 'https://api.fivemerr.com/v1/media/images' -- Enter the API URL here
local WebHookKey = 'WEBHOOKKEY' -- Add this new var containing your API Key
```

* On line 585/586 locate and find the following callback registration event

```lua
QBCore.Functions.CreateCallback('qb-phone:server:GetWebhook', function(_, cb)
    if WebHook ~= '' then
        cb(WebHook)
    else
        print('Set your webhook to ensure that your camera will work!!!!!! Set this on line 10 of the server sided script!!!!!')
        cb(nil)
    end
end)
```

Found it? Great!

Now replace it to this:

```lua
QBCore.Functions.CreateCallback('qb-phone:server:GetWebhook', function(_, cb)
    if WebHook ~= '' then
        cb(WebHook, WebHookKey)
    else
        print('Set your webhook to ensure that your camera will work!!!!!! Set this on line 10 of the server sided script!!!!!')
        cb(nil)
    end
end)
```

## Client File Change

* Navigate to `qb-phone/main/client/main.lua`
* Search for `exports['screenshot-basic']:requestScreenshotUpload` within this file
* You should find something *similar* to this:

```lua
QBCore.Functions.TriggerCallback('qb-phone:server:GetWebhook', function(hook)
    if not hook then
        QBCore.Functions.Notify('Camera not setup', 'error')
        return
    end
    exports['screenshot-basic']:requestScreenshotUpload(tostring(hook), 'files[]', function(data)
        SaveToInternalGallery()
        local image = json.decode(data)
        DestroyMobilePhone()
        CellCamActivate(false, false)
        TriggerServerEvent('qb-phone:server:addImageToGallery', image.attachments[1].proxy_url)
        Wait(400)
        TriggerServerEvent('qb-phone:server:getImageFromGallery')
        cb(json.encode(image.attachments[1].proxy_url))
        takePhoto = false
    end)
end)
```

Found it? Great!

Now update it to this:

```lua
QBCore.Functions.TriggerCallback('qb-phone:server:GetWebhook', function(hook, key)
    if not hook or not key then
        QBCore.Functions.Notify('Camera not setup', 'error')
        return
    end
    exports['screenshot-basic']:requestScreenshotUpload(tostring(hook), 'file', {
        headers = {
            Authorization = key
        } 
    }, function(data)
            SaveToInternalGallery()
            local image = json.decode(data)
            local link = (image and image.url) or 'invalid_url'
            DestroyMobilePhone()
            CellCamActivate(false, false)
            TriggerServerEvent('qb-phone:server:addImageToGallery', link)
            Wait(400)
            TriggerServerEvent('qb-phone:server:getImageFromGallery')
            cb(json.encode(link))
            takePhoto = false
    end)
end)
```

Restart your `qb-phone` **or** server and you're done 🎉!


# LB Phone

## Set your config to "Custom".

located: lb-phone/config/config.lua

![image](https://github.com/FiveMerr/documents/assets/112778590/5084d36d-f9c2-4d86-bad1-1a8ccb580327)

## Create a MEDIA API key and add it below to all 3

Located: lb-phone/server/apiKeys.lua

![image](https://github.com/FiveMerr/documents/assets/112778590/b8eac3e8-287e-495d-aeac-7f338d48ba66)

## On UploadMethods at Custom. Replace for this

Located: lb-phone/shared/upload.lua

```lua
    Custom = {
        Video = {
            url = "https://api.fivemerr.com/v1/media/videos",
            field = "file", -- The field name (formData)
            headers = { -- headers to send when uploading
                ["Authorization"] = "API_KEY"
            },
            error = {
                path = "success", -- The path to the error value (res.success)
                value = false -- If the path is equal to this value, it's an error
            },
            success = {
                path = "url" -- The path to the video file (res.url)
            },
        },
        Image = {
            url = "https://api.fivemerr.com/v1/media/images",
            field = "file", -- The field name (formData)
            headers = { -- headers to send when uploading
                ["Authorization"] = "API_KEY"
            },
            error = {
                path = "success", -- The path to the error value (res.success)
                value = false -- If the path is equal to this value, it's an error
            },
            success = {
                path = "url" -- The path to the image file (res.url)
            },
        },
        Audio = {
            url = "https://api.fivemerr.com/v1/media/audios",
            field = "file", -- The field name (formData)
            headers = { -- headers to send when uploading
                ["Authorization"] = "API_KEY"
            },
            error = {
                path = "success", -- The path to the error value (res.success)
                value = false -- If the path is equal to this value, it's an error
            },
            success = {
                path = "url" -- The path to the audio file (res.url)
            },
        },
    },
```

Should look like this now:&#x20;

![image](https://github.com/FiveMerr/documents/assets/112778590/93a3ba7c-f742-4fbc-bb66-99a00da6233a)

Restart your phone script and you're all set!


# Road Phone

Fivemerr is now supported as of their 1.1.0 update.

**Please create a** **MEDIA API key on** [**https://fivemerr.com**](https://fivemerr.com/)

**Configuring**

1. Open `roadphone/config.lua`, and select fivemerr as uploadMethod
2. Open `roadphone/API.lua`
3. Set your **Fivemerr** api key in `Cfg.uploadMethodKey`

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2FlceOTc7u9H4Y46YwQbuT%2Fimage.png?alt=media&amp;token=3e98bc91-1247-4b4b-b49e-7d759adbbf04" alt=""><figcaption></figcaption></figure>


# NPWD

Resource can be located [here.](https://github.com/project-error/npwd)\
\
Travel to [config.default.json](https://github.com/project-error/npwd/blob/master/config.default.json#L32).

Edit the following code block to look as below:

```json
"images": {
    "url": "https://api.fivemerr.com/v1/media/images",
    "type": "file",
    "imageEncoding": "webp",
    "contentType": "multipart/form-data",
    "useContentType": false,
    "authorizationHeader": "Authorization",
    "authorizationPrefix": "",
    "useAuthorization": true,
    "returnedDataIndexes": ["url"]
  },
```

Add the following to the lines to [`imageSafety`](https://github.com/project-error/npwd/blob/43fea82c1f838ad5e5e258fa9184fe43ffba571c/config.default.json#L43)

```json
files.fivemerr.com
api.fivemerr.com
```


# JP Phone

Integration has been completed and is very simple.&#x20;

Look at their [docs](https://joaos-organization-3.gitbook.io/jpresources-documentation/installation/phone-system/installation-page/qbcore#using-fivemerr) here and a video for setup.

{% embed url="<https://www.youtube.com/watch?v=BzcHieVqP1k>" %}


# nPhone

As of version nPhone 1.1 Fivemerr is now supported.

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2FF00aGzAEWxy6yCH14Wdb%2Fimage.png?alt=media&amp;token=bea12f7a-a54d-4cff-bc21-a2e01c1cd385" alt=""><figcaption></figcaption></figure>


# okokPhone

Make sure your phone is at least on version 0.1.4.

Set `UploadMethod` as 'fivemerr' on `config/config.lua`.

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2FcBGiHKsN43Bsm0Lv0TkY%2Fimage.png?alt=media&amp;token=c63190cc-beb0-44a8-9320-4ae77f5b6c91" alt=""><figcaption></figcaption></figure>

Create MEDIA or individuals API keys from your dashboard and add them at `config/api.json`

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2Fvs5usKfE5N3KDxG3J4F7%2Fimage.png?alt=media&amp;token=c6f916f2-8ac9-4078-904d-52c8929cdad6" alt=""><figcaption></figcaption></figure>


# GKS Phone

Fivemerr is now supported with their latest phone update.\
\
Visit their docs page [here](https://docs.gkshop.org/qb-information/gksphonev2/installation#step-3-serverconfig.lua) for setting up Fivemerr.


# YSeries Phone

We spoke with the YSeries team and they will support Fivemerr in their next update.


# QS Phone

We will not be providing any integration for this phone or any related resources. You may use Fivemerr if you choose, but we will not be offering documentation or support for any of their resources. Please refrain from requesting assistance in this regard.


# Project Sloth

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2F3mdk4eGFFqMZ0DNsiRbn%2Fimage.png?alt=media&amp;token=24b6d900-8b60-4a38-bed5-5a30f97f487c" alt=""><figcaption></figcaption></figure>

Passionate developers and designers with a primary focus on providing quality resources. Our resources are open source and entirely free for all of the FiveM community to enjoy and use.

Discord: <https://discord.gg/projectsloth>


# ps-mdt

Make sure to use version 2.7.0 or higher.

Set the config below to true.

```lua
Config.FivemerrMugShot = true
```

Create a MEDIA API key and add it to server/main.lua line 19.

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2FFUaKWmi5r2JpaM4GOsio%2Fimage.png?alt=media&amp;token=affb2af2-19c5-4210-9bf0-f74f24b08b9e" alt=""><figcaption><p>Add MEDIA API Key</p></figcaption></figure>

&#x20;That's it. Now your images are uploaded and mug shots are added.<br>


# ps-adminmenu


# ps-camera


# Power Scripts

https\://power-scripts.com/

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2FYh1CP8Fi9Bm17B0ieT0a%2Fimage.png?alt=media&amp;token=002fd318-e5d5-4bdb-a25e-a94eae6ace0e" alt=""><figcaption></figcaption></figure>


# power\_dashcams

Make sure to use the latest release of Power Dashcams V2 available on Keymaster.

Create a VIDEO API key and add it to server\_functions.lua line 7. FiveMerr is selected as the API service by default.

<figure><img src="https://4276166755-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FULgrnJMgJB6I6zo9f4c6%2Fuploads%2Fgit-blob-5fe26f9a2dadd6e655e9e7c56b8b8922ab7598ed%2Fdashcams_api_settings.png?alt=media" alt=""><figcaption><p>Add VIDEO API Key</p></figcaption></figure>

Your recorded videos will now be uploaded to FiveMerr and available in game within your dashcam tablet!\\


# Spy Scripts


# spy-bodycam

This feature is available from version 2.5.0 or higher.

## Steps:

1. Set the `Upload.ServiceUsed` to 'fivemerr' in `server/upload_config.lua`:

   ```lua
   Upload.ServiceUsed = 'fivemerr'
   ```
2. Create a `Videos Only` token and place it in the `Upload.Token` field in `server/upload_config.lua`:

   ```lua
   Upload.Token = 'YOUR_TOKEN'
   ```

Once you have completed these steps, the configuration is finished.


