Skip to content
SkinPlata
API reference · v1.1.0

SkinPlata API

Take CS2, Dota 2 and Rust skins as payment and send skins to your customers — with one REST API and signed webhooks.

https://skinplata.com/api/v1
OpenAPI JSON OpenAPI YAML

Import the OpenAPI file into Postman, Insomnia, Bruno or your code generator to get a ready client.

Quickstart

Get your keys

Open an account and submit a project. Your project key and test secret are shown at once; the live secret works once we approve the project.

Create a payment

Call POST /payments with your order id, then send the customer to pay_url.

Listen for the webhook

Fulfil the order on deposit.success. In test mode, drive outcomes from the checkout's test buttons or POST /test/payments/{id}/simulate.

curl -X POST 'https://skinplata.com/api/v1/payments' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret' \
  -H 'Content-Type: application/json' \
  -d '{"order_id":"inv-1042","game":"cs2","currency":"usd","min_amount":5,"metadata":{"user_id":"8812"}}'

Authentication

Every request carries two headers. Keep the secret on your server — never in a browser or an app.

HeaderValue
X-Project-KeyYour public project key, pk_…
X-Project-Secretsk_live_… for real money, sk_test_… for test mode

An optional IP allow-list is in the project settings. Rotating a secret stops the old one at once.

Errors & limits

Errors use a matching HTTP status and one shape:

{
    "error": {
        "code": "invalid_request",
        "message": "order_id is required (1–128 printable characters, no spaces).",
        "param": "order_id"
    }
}
StatusCodes
401unauthenticated, invalid_credentials
402insufficient_funds
403project_inactive, project_disabled, ip_not_allowed, test_mode_only
404not_found
409duplicate_order_id, not_in_trade_protection, invalid_transition, no_webhook_url
422invalid_request (see param) and refusals from the market
429rate_limited — 600 requests a minute per project, 1,200 per IP; see Retry-After
503temporarily_unavailable — retry later; nothing was charged

Lists take page and limit (1–100) and answer {"object":"list","data":[…],"page","limit","total","has_more"}. Creating calls are idempotent by your reference: a repeated order_id answers 409, a repeated custom_id returns the first purchase.

Test mode

Use your sk_test_ secret and everything is simulated: real skin names and prices, no real trades, a separate test balance that starts at $1,000.00 (reset it on the project page). Objects carry "livemode": false, responses the header SkinPlata-Test: 1, webhooks go to the same URL with the same signature. Test objects are invisible to the live secret and the other way round.

Webhooks

Set the URL on the project page. We send a POST with a JSON body for every event below, signed with your whsec_ secret. Answer any 2xx; anything else is retried at 1 min, 5 min, 15 min, 1 h, 3 h, 6 h, 12 h and 24 h. Failed deliveries can be resent from the dashboard.

POST /your/webhook
Content-Type: application/json
SkinPlata-Event: deposit.success
SkinPlata-Delivery: wh_9a8b7c6d5e4f3a2b1c0d9e8f
SkinPlata-Signature: t=1793920000,v1=5f2c…

{
    "id": "wh_9a8b7c6d5e4f3a2b1c0d9e8f",
    "type": "deposit.success",
    "created": 1793920000,
    "livemode": true,
    "data": {
        "id": "dep_8f2c1a9b4e7d6c3f2a1b0c9d",
        "object": "payment",
        "order_id": "inv-1042",
        "status": "success",
        "net_usd": 14.2,
        "…": "…"
    }
}

Check the signature

SkinPlata-Signature is t=<unix time>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">. Use the raw body exactly as received, refuse timestamps older than 5 minutes, compare in constant time. Then re-read the object before you hand anything out.

<?php
$raw    = file_get_contents('php://input');
$header = $_SERVER['HTTP_SKINPLATA_SIGNATURE'] ?? '';
$secret = 'whsec_your_secret';

$parts = [];
foreach (explode(',', $header) as $kv) {
    [$k, $v] = array_pad(explode('=', trim($kv), 2), 2, '');
    $parts[$k][] = $v;
}
$t   = (int) ($parts['t'][0] ?? 0);
$sig = hash_hmac('sha256', $t . '.' . $raw, $secret);
$ok  = abs(time() - $t) <= 300 && array_filter($parts['v1'] ?? [], fn ($v) => hash_equals($sig, $v));
if (!$ok) { http_response_code(400); exit; }

$event = json_decode($raw, true);
// Credit your customer only after re-reading the object: GET /payments/{id}
http_response_code(200);

Events

EventWhen
deposit.pendingTrade offer sent to the customer.
deposit.in_holdCustomer accepted; Steam trade protection running.
deposit.hold_approvedYou released it early (your side only).
deposit.successFinal. Your balance is credited — fulfil the order now.
deposit.failDeclined, cancelled or timed out. Nothing credited.
deposit.hold_returnedReversed during trade protection; a credit is taken back.
deposit.expiredThe link was never used.
purchase.creating_tradeSkin bought, trade being created.
purchase.waiting_acceptTrade offer sent to the recipient.
purchase.acceptedDelivered.
purchase.failedNot delivered; money released or refunded.
purchase.rolled_backTrade reversed after delivery; refunded.
payout.pendingPayout requested.
payout.paidPayout sent (reference included).
payout.rejectedPayout rejected (reason included); money back on your balance.
test.pingSent by "Send test.ping" or POST /webhooks/test.

Embedding the checkout

Link to pay_url, open it in a pop-up, or put embed_url in an iframe. The page posts every status change to your window — use it for your UI, and credit from the webhook.

<iframe src="https://skinplata.com/pay/…?embed=1" width="100%" height="720" style="border:0"></iframe>

<script>
window.addEventListener('message', (e) => {
  if (e.origin !== 'https://skinplata.com' || e.data?.source !== 'skinplata') return;
  // { type: 'payment.status', status: 'pending' | 'in_hold' | 'success' | 'fail' …, payment_id, order_id }
  if (e.data.status === 'success') showThankYou();
});
</script>

Payments

Take skins as payment: hosted payment links or your own item picker.

POST /payments

Create a payment link

Creates a hosted payment. Send the customer to pay_url (or embed embed_url). The payment moves through created → pending → in_hold → success; you get a webhook for every step.

Body application/json

order_id required
string
Your reference. Unique per project and mode. 1–128 printable characters, no spaces.
game
string
Game whose inventory the customer sees first. Default: project setting.
cs2dota2rust
currency
string
Currency prices are shown in. Default: project setting.
usdeurgbpcadaudnzdbrlcnymxnrubuahkztarsclppencop
min_amount
number
Least value the customer must send, in currency.
max_amount
number
Most value accepted, in currency.
trade_url
string
The customer's Steam trade link, if you already have it (skips that step).
success_url
string
https URL for "Back to shop" after a good payment. Default: project setting.
fail_url
string
https URL for "Back to shop" after a failed one.
metadata
object
Up to 20 keys (1–40 of A-Z a-z 0-9 _ . -), text or number values up to 500 characters. Returned on every object and webhook.
expires_in
integer
Seconds until an unused link expires. Default 86400.

Request

curl -X POST 'https://skinplata.com/api/v1/payments' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret' \
  -H 'Content-Type: application/json' \
  -d '{"order_id":"inv-1042","game":"cs2","currency":"usd","min_amount":5,"metadata":{"user_id":"8812"}}'
Response 201 403 project_inactive409 duplicate_order_id422 invalid_request
{
    "id": "dep_8f2c1a9b4e7d6c3f2a1b0c9d",
    "object": "payment",
    "livemode": true,
    "order_id": "inv-1042",
    "status": "success",
    "flow": "hosted",
    "pay_url": "https://skinplata.com/pay/Xr2…",
    "embed_url": "https://skinplata.com/pay/Xr2…?embed=1",
    "game": "cs2",
    "steam_id": "76561198000000042",
    "currency": "usd",
    "amount": 14.2,
    "amount_usd": 14.2,
    "fee_usd": 0,
    "net_usd": 14.2,
    "credited": true,
    "min_amount": 5,
    "max_amount": null,
    "trade_offer_id": "7712345678",
    "trade_offer_url": null,
    "fail_reason": null,
    "hold_until": 1794524800,
    "items": [
        {
            "asset_id": "38271946512",
            "name": "AK-47 | Redline (Field-Tested)",
            "image": "https://community.akamai.steamstatic.com/economy/image/…",
            "price": 14.2,
            "price_usd": 14.2
        }
    ],
    "metadata": {},
    "expires_at": null,
    "created_at": 1793920000,
    "updated_at": 1793920000,
    "completed_at": null
}
POST /payments/direct

Create a direct payment

For your own item picker: read the inventory with GET /inventory, then send the chosen asset_ids. The Steam trade offer is created at once; the answer has status: pending and trade_offer_url.

Body application/json

order_id required
string
Your reference, unique per project and mode.
game required
string
cs2dota2rust
trade_url required
string
The customer's Steam trade link.
asset_ids required
string[]
1–200 asset ids from GET /inventory.
currency
string
usdeurgbpcadaudnzdbrlcnymxnrubuahkztarsclppencop
metadata
object
As on POST /payments.

Request

curl -X POST 'https://skinplata.com/api/v1/payments/direct' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret' \
  -H 'Content-Type: application/json' \
  -d '{"order_id":"inv-1043","game":"cs2","trade_url":"https://steamcommunity.com/tradeoffer/new/?partner=12345678&token=AbCdEfGh","asset_ids":["31502281937","31502281944"],"currency":"usd"}'
Response 201 403 project_inactive409 duplicate_order_id422 invalid_request503 temporarily_unavailable
{
    "id": "dep_8f2c1a9b4e7d6c3f2a1b0c9d",
    "object": "payment",
    "livemode": true,
    "order_id": "inv-1042",
    "status": "success",
    "flow": "hosted",
    "pay_url": "https://skinplata.com/pay/Xr2…",
    "embed_url": "https://skinplata.com/pay/Xr2…?embed=1",
    "game": "cs2",
    "steam_id": "76561198000000042",
    "currency": "usd",
    "amount": 14.2,
    "amount_usd": 14.2,
    "fee_usd": 0,
    "net_usd": 14.2,
    "credited": true,
    "min_amount": 5,
    "max_amount": null,
    "trade_offer_id": "7712345678",
    "trade_offer_url": null,
    "fail_reason": null,
    "hold_until": 1794524800,
    "items": [
        {
            "asset_id": "38271946512",
            "name": "AK-47 | Redline (Field-Tested)",
            "image": "https://community.akamai.steamstatic.com/economy/image/…",
            "price": 14.2,
            "price_usd": 14.2
        }
    ],
    "metadata": {},
    "expires_at": null,
    "created_at": 1793920000,
    "updated_at": 1793920000,
    "completed_at": null
}
GET /payments

List payments

Newest first. Only objects of the mode of your secret (live or test).

Parameters

status
query · string
Filter by status.
createdpendingin_holdhold_approvedsuccessfailhold_returnedexpired
order_id
query · string
Find by your order id.
steam_id
query · string
Find by the customer's SteamID64.
from
query · integer
Created at or after (unix time).
to
query · integer
Created at or before (unix time).
page
query · integer
Page, from 1.
limit
query · integer
Items per page, 1–100 (default 25).

Request

curl 'https://skinplata.com/api/v1/payments' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200
{
    "object": "list",
    "livemode": true,
    "data": [
        {
            "id": "dep_8f2c1a9b4e7d6c3f2a1b0c9d",
            "object": "payment",
            "livemode": true,
            "order_id": "inv-1042",
            "status": "success",
            "flow": "hosted",
            "pay_url": "https://skinplata.com/pay/Xr2…",
            "embed_url": "https://skinplata.com/pay/Xr2…?embed=1",
            "game": "cs2",
            "steam_id": "76561198000000042",
            "currency": "usd",
            "amount": 14.2,
            "amount_usd": 14.2,
            "fee_usd": 0,
            "net_usd": 14.2,
            "credited": true,
            "min_amount": 5,
            "max_amount": null,
            "trade_offer_id": "7712345678",
            "trade_offer_url": null,
            "fail_reason": null,
            "hold_until": 1794524800,
            "items": [
                {
                    "asset_id": "38271946512",
                    "name": "AK-47 | Redline (Field-Tested)",
                    "image": "https://community.akamai.steamstatic.com/economy/image/…",
                    "price": 14.2,
                    "price_usd": 14.2
                }
            ],
            "metadata": {},
            "expires_at": null,
            "created_at": 1793920000,
            "updated_at": 1793920000,
            "completed_at": null
        }
    ],
    "page": 1,
    "limit": 25,
    "total": 1,
    "has_more": false
}
GET /payments/{id}

Get a payment

Parameters

id required
path · string
Payment id (dep_…).

Request

curl 'https://skinplata.com/api/v1/payments/dep_8f2c1a9b4e7d6c3f2a1b0c9d' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200 404 not_found
{
    "id": "dep_8f2c1a9b4e7d6c3f2a1b0c9d",
    "object": "payment",
    "livemode": true,
    "order_id": "inv-1042",
    "status": "success",
    "flow": "hosted",
    "pay_url": "https://skinplata.com/pay/Xr2…",
    "embed_url": "https://skinplata.com/pay/Xr2…?embed=1",
    "game": "cs2",
    "steam_id": "76561198000000042",
    "currency": "usd",
    "amount": 14.2,
    "amount_usd": 14.2,
    "fee_usd": 0,
    "net_usd": 14.2,
    "credited": true,
    "min_amount": 5,
    "max_amount": null,
    "trade_offer_id": "7712345678",
    "trade_offer_url": null,
    "fail_reason": null,
    "hold_until": 1794524800,
    "items": [
        {
            "asset_id": "38271946512",
            "name": "AK-47 | Redline (Field-Tested)",
            "image": "https://community.akamai.steamstatic.com/economy/image/…",
            "price": 14.2,
            "price_usd": 14.2
        }
    ],
    "metadata": {},
    "expires_at": null,
    "created_at": 1793920000,
    "updated_at": 1793920000,
    "completed_at": null
}
POST /payments/{id}/release

Release a payment early

For a payment in Steam trade protection (in_hold): tells your system now (deposit.hold_approved). Your balance is still credited only when the trade is final.

Parameters

id required
path · string
Payment id (dep_…).

Request

curl -X POST 'https://skinplata.com/api/v1/payments/dep_8f2c1a9b4e7d6c3f2a1b0c9d/release' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response 200 404 not_found409 not_in_trade_protection
{
    "id": "dep_8f2c1a9b4e7d6c3f2a1b0c9d",
    "object": "payment",
    "livemode": true,
    "order_id": "inv-1042",
    "status": "success",
    "flow": "hosted",
    "pay_url": "https://skinplata.com/pay/Xr2…",
    "embed_url": "https://skinplata.com/pay/Xr2…?embed=1",
    "game": "cs2",
    "steam_id": "76561198000000042",
    "currency": "usd",
    "amount": 14.2,
    "amount_usd": 14.2,
    "fee_usd": 0,
    "net_usd": 14.2,
    "credited": true,
    "min_amount": 5,
    "max_amount": null,
    "trade_offer_id": "7712345678",
    "trade_offer_url": null,
    "fail_reason": null,
    "hold_until": 1794524800,
    "items": [
        {
            "asset_id": "38271946512",
            "name": "AK-47 | Redline (Field-Tested)",
            "image": "https://community.akamai.steamstatic.com/economy/image/…",
            "price": 14.2,
            "price_usd": 14.2
        }
    ],
    "metadata": {},
    "expires_at": null,
    "created_at": 1793920000,
    "updated_at": 1793920000,
    "completed_at": null
}
GET /inventory

Read a customer's inventory

Tradable items with live prices, for POST /payments/direct. Items with available: false cannot be accepted.

Parameters

trade_url required
query · string
The customer's Steam trade link.
game
query · string
Game. Default: project setting.
cs2dota2rust
currency
query · string
Currency of price. Default: project setting.

Request

curl 'https://skinplata.com/api/v1/inventory?trade_url=https%3A%2F%2Fsteamcommunity.com%2Ftradeoffer%2Fnew%2F%3Fpartner%3D12345678%26token%3DAbCdEfGh&game=cs2' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200 422 invalid_request503 temporarily_unavailable
{
    "object": "inventory",
    "livemode": true,
    "game": "",
    "currency": "",
    "steam_id": "",
    "items": [],
    "total_available": 0.0
}

Market

What is in stock on the skin market.

GET /market/items

Skins in stock

Every skin you can buy right now with its lowest price.

Parameters

game
query · string
Game (default cs2).
cs2dota2rust
q
query · string
Words that must all appear in the name.
page
query · integer
Page, from 1.
limit
query · integer
Items per page, 1–100 (default 25).

Request

curl 'https://skinplata.com/api/v1/market/items?game=cs2' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200
{
    "object": "list",
    "livemode": true,
    "data": [
        {
            "object": "market_item",
            "name": "AK-47 | Redline (Field-Tested)",
            "price_usd": 25.63,
            "count": 60
        }
    ],
    "page": 1,
    "limit": 25,
    "total": 1,
    "has_more": false
}
GET /market/offers

Live offers for one skin

Every offer of an exact market name, cheapest first. Use item_id with POST /purchases to buy that exact item.

Parameters

game required
query · string
Game.
cs2dota2rust
name required
query · string
Exact market name.

Request

curl 'https://skinplata.com/api/v1/market/offers?game=cs2&name=AK-47%20%7C%20Redline%20%28Field-Tested%29' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200
{
    "object": "list",
    "livemode": true,
    "data": [
        {
            "object": "market_offer",
            "item_id": 0,
            "name": "",
            "price_usd": 0.0,
            "float": null,
            "delivery_type": null,
            "stickers": [],
            "image": ""
        }
    ],
    "page": 1,
    "limit": 25,
    "total": 1,
    "has_more": false
}

Purchases

Buy a skin with your balance and send it to a trade link.

POST /purchases

Buy a skin and send it

Holds max_price (plus the market fee, if any) on your balance, buys, then charges the real price and releases the rest. Repeating a custom_id returns the existing purchase (200) — safe to retry. If the skin does not reach the customer, the charge comes back.

Body application/json

custom_id required
string
Your reference; makes the call idempotent.
trade_url required
string
The customer's Steam trade link.
max_price required
number
Highest item price in USD you accept.
item_id
integer
A specific offer from GET /market/offers. Or give name + game.
name
string
Exact market name: the cheapest offer under max_price is bought.
game
string
Needed with name.
cs2dota2rust
delivery_types
integer[]
1 = instant, 2 = regular.
test_outcome
string
Test mode only: how the simulated purchase ends.
acceptedwaiting_acceptfailed

Request

curl -X POST 'https://skinplata.com/api/v1/purchases' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret' \
  -H 'Content-Type: application/json' \
  -d '{"custom_id":"wd-77","trade_url":"https://steamcommunity.com/tradeoffer/new/?partner=12345678&token=AbCdEfGh","max_price":30,"name":"AK-47 | Redline (Field-Tested)","game":"cs2"}'
Response 201 402 insufficient_funds403 project_inactive422 invalid_request503 temporarily_unavailable
{
    "id": "pur_1c2d3e4f5a6b7c8d9e0f1a2b",
    "object": "purchase",
    "livemode": true,
    "custom_id": "wd-77",
    "status": "waiting_accept",
    "game": "",
    "item_name": "AK-47 | Redline (Field-Tested)",
    "item_id": null,
    "steam_id": null,
    "max_price_usd": 30,
    "price_usd": 25.63,
    "fee_usd": 0,
    "charged_usd": 25.63,
    "refunded_usd": 0,
    "trade_offer_id": null,
    "error_reason": null,
    "created_at": 1793920000,
    "updated_at": 1793920000
}
GET /purchases

List purchases

Parameters

status
query · string
Filter by status.
pendingunknowncreating_tradewaiting_acceptacceptedcanceledtimeoutinvalid_trade_tokenuser_not_tradabletrade_create_errorrollback_userrollback_supplierfailed
custom_id
query · string
Find by your reference.
page
query · integer
Page, from 1.
limit
query · integer
Items per page, 1–100 (default 25).

Request

curl 'https://skinplata.com/api/v1/purchases' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200
{
    "object": "list",
    "livemode": true,
    "data": [
        {
            "id": "pur_1c2d3e4f5a6b7c8d9e0f1a2b",
            "object": "purchase",
            "livemode": true,
            "custom_id": "wd-77",
            "status": "waiting_accept",
            "game": "",
            "item_name": "AK-47 | Redline (Field-Tested)",
            "item_id": null,
            "steam_id": null,
            "max_price_usd": 30,
            "price_usd": 25.63,
            "fee_usd": 0,
            "charged_usd": 25.63,
            "refunded_usd": 0,
            "trade_offer_id": null,
            "error_reason": null,
            "created_at": 1793920000,
            "updated_at": 1793920000
        }
    ],
    "page": 1,
    "limit": 25,
    "total": 1,
    "has_more": false
}
GET /purchases/{id}

Get a purchase

Parameters

id required
path · string
Purchase id (pur_…).

Request

curl 'https://skinplata.com/api/v1/purchases/pur_1c2d3e4f5a6b7c8d9e0f1a2b' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200 404 not_found
{
    "id": "pur_1c2d3e4f5a6b7c8d9e0f1a2b",
    "object": "purchase",
    "livemode": true,
    "custom_id": "wd-77",
    "status": "waiting_accept",
    "game": "",
    "item_name": "AK-47 | Redline (Field-Tested)",
    "item_id": null,
    "steam_id": null,
    "max_price_usd": 30,
    "price_usd": 25.63,
    "fee_usd": 0,
    "charged_usd": 25.63,
    "refunded_usd": 0,
    "trade_offer_id": null,
    "error_reason": null,
    "created_at": 1793920000,
    "updated_at": 1793920000
}

Balance

Your project, its balance and every booking.

GET /status

Service status

Whether payments can be taken right now.

Request

curl 'https://skinplata.com/api/v1/status' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200
{
    "object": "status",
    "livemode": true,
    "operational": true,
    "time": 1793920000
}
GET /project

Your project

Request

curl 'https://skinplata.com/api/v1/project' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200
{
    "id": "",
    "object": "project",
    "livemode": true,
    "name": "",
    "website": "",
    "status": "pending",
    "live_enabled": true,
    "deposit_fee_percent": 0.0,
    "market_fee_percent": 0.0,
    "default_game": "",
    "default_currency": "",
    "webhook_url": null,
    "balance": {
        "available_usd": 0.0,
        "reserved_usd": 0.0
    }
}
GET /balance

Balance

available can be spent or paid out; reserved is held for open purchases and payouts.

Request

curl 'https://skinplata.com/api/v1/balance' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200
{
    "object": "balance",
    "livemode": true,
    "currency": "usd",
    "available": 1290.55,
    "reserved": 95
}
GET /balance/history

Balance history

Every booking, newest first.

Parameters

type
query · string
Filter by type.
depositdeposit_reversalreservereleasepurchasepurchase_refundadjustmentpayouttest_credit
page
query · integer
Page, from 1.
limit
query · integer
Items per page, 1–100 (default 25).

Request

curl 'https://skinplata.com/api/v1/balance/history' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200
{
    "object": "list",
    "livemode": true,
    "data": [
        {
            "id": "le_118",
            "object": "balance_entry",
            "type": "deposit",
            "amount": 0.0,
            "balance_after": 0.0,
            "reserved_after": 0.0,
            "description": "",
            "reference": null,
            "created_at": 1793920000
        }
    ],
    "page": 1,
    "limit": 25,
    "total": 1,
    "has_more": false
}

Payouts

Payouts are requested in the dashboard; read them here.

GET /payouts

List payouts

Parameters

status
query · string
Filter by status.
pendingpaidrejected
page
query · integer
Page, from 1.
limit
query · integer
Items per page, 1–100 (default 25).

Request

curl 'https://skinplata.com/api/v1/payouts' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200
{
    "object": "list",
    "livemode": true,
    "data": [
        {
            "id": "po_4a5b6c7d8e9f0a1b2c3d4e5f",
            "object": "payout",
            "status": "pending",
            "project": null,
            "method": "crypto",
            "destination": {
                "id": null,
                "label": null,
                "summary": null
            },
            "amount_usd": 0.0,
            "fee_usd": 0.0,
            "net_usd": 0.0,
            "reference": null,
            "reason": null,
            "created_at": 1793920000,
            "completed_at": null
        }
    ],
    "page": 1,
    "limit": 25,
    "total": 1,
    "has_more": false
}
GET /payouts/{id}

Get a payout

Parameters

id required
path · string
Payout id (po_…).

Request

curl 'https://skinplata.com/api/v1/payouts/po_4a5b6c7d8e9f0a1b2c3d4e5f' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret'
Response 200 404 not_found
{
    "id": "po_4a5b6c7d8e9f0a1b2c3d4e5f",
    "object": "payout",
    "status": "pending",
    "project": null,
    "method": "crypto",
    "destination": {
        "id": null,
        "label": null,
        "summary": null
    },
    "amount_usd": 0.0,
    "fee_usd": 0.0,
    "net_usd": 0.0,
    "reference": null,
    "reason": null,
    "created_at": 1793920000,
    "completed_at": null
}

Webhooks

Check your endpoint.

POST /webhooks/test

Send a test.ping

Sends test.ping to the webhook URL of the project and returns the delivery with the answer your endpoint gave.

Request

curl -X POST 'https://skinplata.com/api/v1/webhooks/test' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response 200 409 no_webhook_url
{
    "id": "wh_9a8b7c6d5e4f3a2b1c0d9e8f",
    "object": "webhook_delivery",
    "livemode": true,
    "type": "deposit.pending",
    "url": "",
    "status": "pending",
    "attempts": 0,
    "last_http_code": null,
    "last_error": null,
    "next_attempt_at": null,
    "delivered_at": null,
    "created_at": 1793920000
}

Test mode

Drive simulated payments and purchases (sk_test_ secret only).

POST /test/payments/{id}/simulate

Simulate a payment outcome

A payment nobody started yet first gets sample items sent. Same webhooks as live.

Parameters

id required
path · string
Test payment id.

Body application/json

outcome required
string
in_holdhold_approvedsuccessfailhold_returnedexpired

Request

curl -X POST 'https://skinplata.com/api/v1/test/payments/dep_8f2c1a9b4e7d6c3f2a1b0c9d/simulate' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret' \
  -H 'Content-Type: application/json' \
  -d '{"outcome":"success"}'
Response 200 403 test_mode_only409 invalid_transition
{
    "id": "dep_8f2c1a9b4e7d6c3f2a1b0c9d",
    "object": "payment",
    "livemode": true,
    "order_id": "inv-1042",
    "status": "success",
    "flow": "hosted",
    "pay_url": "https://skinplata.com/pay/Xr2…",
    "embed_url": "https://skinplata.com/pay/Xr2…?embed=1",
    "game": "cs2",
    "steam_id": "76561198000000042",
    "currency": "usd",
    "amount": 14.2,
    "amount_usd": 14.2,
    "fee_usd": 0,
    "net_usd": 14.2,
    "credited": true,
    "min_amount": 5,
    "max_amount": null,
    "trade_offer_id": "7712345678",
    "trade_offer_url": null,
    "fail_reason": null,
    "hold_until": 1794524800,
    "items": [
        {
            "asset_id": "38271946512",
            "name": "AK-47 | Redline (Field-Tested)",
            "image": "https://community.akamai.steamstatic.com/economy/image/…",
            "price": 14.2,
            "price_usd": 14.2
        }
    ],
    "metadata": {},
    "expires_at": null,
    "created_at": 1793920000,
    "updated_at": 1793920000,
    "completed_at": null
}
POST /test/purchases/{id}/simulate

Simulate a purchase outcome

Parameters

id required
path · string
Test purchase id.

Body application/json

outcome required
string
acceptedwaiting_acceptcanceledtimeoutrollback_usertrade_create_error

Request

curl -X POST 'https://skinplata.com/api/v1/test/purchases/pur_1c2d3e4f5a6b7c8d9e0f1a2b/simulate' \
  -H 'X-Project-Key: pk_your_key' \
  -H 'X-Project-Secret: sk_test_your_secret' \
  -H 'Content-Type: application/json' \
  -d '{"outcome":"canceled"}'
Response 200 403 test_mode_only409 invalid_transition
{
    "id": "pur_1c2d3e4f5a6b7c8d9e0f1a2b",
    "object": "purchase",
    "livemode": true,
    "custom_id": "wd-77",
    "status": "waiting_accept",
    "game": "",
    "item_name": "AK-47 | Redline (Field-Tested)",
    "item_id": null,
    "steam_id": null,
    "max_price_usd": 30,
    "price_usd": 25.63,
    "fee_usd": 0,
    "charged_usd": 25.63,
    "refunded_usd": 0,
    "trade_offer_id": null,
    "error_reason": null,
    "created_at": 1793920000,
    "updated_at": 1793920000
}

Statuses

Payment

createdAwaiting customer
pendingOffer sent
in_holdTrade protection
hold_approvedReleased early
successPaid
failFailed
hold_returnedReversed
expiredExpired

Purchase

pendingProcessing
unknownChecking
creating_tradeCreating trade
waiting_acceptOffer sent
acceptedDelivered
canceledDeclined
timeoutNot accepted
invalid_trade_tokenBad trade link
user_not_tradableCustomer cannot trade
trade_create_errorTrade failed
rollback_userReturned by customer
rollback_supplierReturned by seller
failedFailed