Save Trades
SaveTradeAsync persists a completed trade to Traderie for player history, marketplace data, and value calculations. Trade saving is server-only.
Importing
Call this from a server Script or server ModuleScript. Do not call SaveTradeAsync from a LocalScript.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Traderie = require(ReplicatedStorage:WaitForChild("Traderie"):WaitForChild("API"))
ReplicatedStorage.Traderie.API is the public SDK entrypoint for both server and client code. On the server, that entrypoint loads the server runtime from ServerScriptService/Traderie/API, so API keys and trade-saving internals stay server-only.
Credentials are loaded from the generated ServerScriptService/Traderie/Config/Config module. Use Traderie API Settings in the Studio plugin to set your API key before saving trades. If no credentials are configured, requests return not_configured.
You do not configure a Traderie schema or game id manually. The SDK derives the schema automatically from the current Roblox experience as roblox_<game.GameId>.
Syntax
local Trades = Traderie:GetService("Trades")
Trades:SaveTradeAsync(tradeData: table) -> table
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
tradeData | table | ✅ | A structured table representing the full trade record. |
tradeData.userA | table | ✅ | Data for the first user in the trade. |
tradeData.userA.id | number | ✅ | Roblox UserId of the first player. |
tradeData.userA.username | string | ✅ | Username of the first player. Usernames are necessary in case the user doesn't have a Traderie account, we create one for them. |
tradeData.userA.items | table[] | ✅ | List of items offered by the first player. |
tradeData.userA.items[].id | string | ✅ | Identifier of the item being traded. |
tradeData.userA.items[].quantity | number | ✅ | Quantity of the item. |
tradeData.userA.items[].properties | table[] | No | Optional item properties such as variants, mutations, or traits. |
tradeData.userB | table | ✅ | Data for the second user in the trade. |
tradeData.userB.id | number | ✅ | Roblox UserId of the second player. |
tradeData.userB.username | string | ✅ | Username of the second player. |
tradeData.userB.items | table[] | ✅ | List of items offered by the second player. |
tradeData.userB.items[].id | string | ✅ | Identifier of the item being traded. |
tradeData.userB.items[].quantity | number | ✅ | Quantity of the item. |
tradeData.userB.items[].properties | table[] | No | Optional item properties such as variants, mutations, or traits. |
Returns
| Type | Description |
|---|---|
table | Returns a response table. response.ok == true means the trade was saved. Failed responses include a code value such as not_configured or bad_trade. |
Example Usage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Traderie = require(ReplicatedStorage:WaitForChild("Traderie"):WaitForChild("API"))
local Trades = Traderie:GetService("Trades")
local response = Trades:SaveTradeAsync({
userA = {
id = playerA.UserId,
username = playerA.Name,
items = {
{ id = "egg_gold", quantity = 1 },
{ id = "sword_robux", quantity = 2 },
},
},
userB = {
id = playerB.UserId,
username = playerB.Name,
items = {
{ id = "pet_diamond", quantity = 1 },
},
}
})
if not response.ok then
warn("Failed to save Traderie trade:", response.code)
end
Item Properties
Use properties when the traded item has a variant, mutation, trait, or other visible detail that should be tracked separately from the base item id.
{
id = "unusual",
quantity = 1,
properties = {
{
name = "Variant",
value = "Bright",
},
},
}
The id should still match the stable item id from your catalog. Put generated or player-specific details in properties instead of creating a new base item id for every combination.
Testing
You can test SaveTradeAsync from Studio using a server and client test session. You do not need to publish the integration to a live public server before checking that the trade payload reaches Traderie.
Debugging Failed Saves
If response.ok is false, inspect the full response while you are testing:
local HttpService = game:GetService("HttpService")
if not response.ok then
warn("Failed to save Traderie trade:", response.code)
warn("Status code:", response.statusCode)
if response.payload then
warn("Response body:", HttpService:JSONEncode(response.payload))
end
if response.error then
warn("Request error:", response.error)
end
end
Common failure signals:
| Signal | What to check |
|---|---|
not_configured | The Traderie API key has not been saved with Traderie API Settings. |
http_400 with "at least one item is required" | At least one side is sending an empty or malformed items array. Log the payload you pass to SaveTradeAsync and confirm each item has id and quantity. |
http_400 with a Roblox username or account message | Send the response body to Traderie support so the linked account can be checked. |
bad_response | The HTTP response body was not valid JSON. Inspect response.error. |
Client Usage
Clients cannot configure credentials or save trades. If a LocalScript requires ReplicatedStorage.Traderie.API, it only receives the safe client facade for users and reviews. The Trades service is only available on the server.