Roovet Roovet

Roovet API Docs

Authenticate with Authorization: Bearer <API_KEY>. All responses are JSON.

Current channel: Beta until 2025-12-15
Open API Explorer

Authentication & Scopes

Copy link

Send Authorization: Bearer <API_KEY>. Optional version pin: X-Roovet-Version: .

Keys carry scopes (e.g., wallet:read, shop:write). Endpoints enforce scopes; failures return 403 insufficient_scope.

Rate limiting: 60 req/min per key. We return X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.
Scopes
wallet:read wallet:write shop:read shop:write search:read news:read
Example
curl -H "Authorization: Bearer rvpk_live_..._1234" \
  -H "X-Roovet-Version: " \
  https://roovet.com/api/wallet/balance
const res = await fetch('https://roovet.com/api/wallet/balance', {
  headers: { Authorization: 'Bearer ' + ROOVET_API_KEY, 'X-Roovet-Version': ''+(window.ApiDocsVersion||'2025-09-15')+'' }
});
const json = await res.json();
$ch = curl_init("https://roovet.com/api/wallet/balance");
curl_setopt_array($ch, [
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer ".$_ENV["ROOVET_API_KEY"],
    "X-Roovet-Version: 2025-11-10"
  ],
  CURLOPT_RETURNTRANSFER => true
]);
$resp = curl_exec($ch);
import requests, os
r = requests.get("https://roovet.com/api/wallet/balance", headers={
  "Authorization": f"Bearer {os.getenv('ROOVET_API_KEY')}",
  "X-Roovet-Version": "2025-11-10"
})
print(r.json())

Wallet API Beta

GET /api/wallet/balance wallet:read Open in Explorer

Returns current wallet balance and available amount.

URL
curl -H "Authorization: Bearer <API_KEY>" https://roovet.com/api/wallet/balance
{
  "balance_cents": 12345,
  "available_cents": 12000,
  "currency": "USD",
  "updated_at": "2025-09-20T02:30:00Z"
}
GET /api/wallet/transactions?limit=50&starting_after=txn_... wallet:read Open in Explorer

Cursor-paginated list of transactions (most recent first).

URL
curl "https://roovet.com/api/wallet/transactions?limit=2" -H "Authorization: Bearer <API_KEY>"
{
  "data": [
    {"id":"txn_123","type":"credit","amount_cents":999,"currency":"USD","created_at":"2025-09-20T02:29:00Z"},
    {"id":"txn_122","type":"debit","amount_cents":-499,"currency":"USD","created_at":"2025-09-19T16:10:00Z"}
  ],
  "has_more": true,
  "next_cursor": "txn_122"
}
POST /api/wallet/transfer wallet:write Open in Explorer

Transfer funds to another user by ID or email.

URL
curl -X POST https://roovet.com/api/wallet/transfer \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Idempotency-Key: 5b0d...d4" \
  -H "Content-Type: application/json" \
  -d '{"to":"user_42","amount":12.34,"currency":"USD","note":"Thanks!"}'
{
  "to": "user_id_or_email",
  "amount": 12.34,
  "currency": "USD",
  "note": "optional"
}
{
  "id": "trf_abc123",
  "status": "processing",
  "amount_cents": 1234,
  "currency": "USD",
  "created_at": "2025-09-20T02:31:00Z"
}

Shop API Beta

Copy link
GET/api/shop/products?query=chair&limit=20shop:readOpen in Explorer

Search products and paginate results.

URL
POST/api/shop/cartshop:writeOpen in Explorer

Create/update a cart.

URL
POST/api/shop/checkoutshop:writeOpen in Explorer

Checkout with wallet|card.

URL
GET/api/shop/ordersshop:readOpen in Explorer

List recent orders.

URL

Webhooks & Signing

Copy link

We sign with X-Roovet-Signature (t=<unix>,v1=<hmac>) and X-Roovet-Timestamp. Verify using our HMAC recipe.

Send (server → your app)
// $apiKeyRow: row from rse_api_keys of the integration owner
$secret  = \App\Libraries\WebhookSigner::secretFor($apiKeyRow);
$payload = ["event" => "order.created", "id" => "ord_123", "ts" => time()];
$raw     = json_encode($payload, JSON_UNESCAPED_SLASHES);
$sig     = \App\Libraries\WebhookSigner::sign($raw, $secret);

// Send POST with headers:
//   Content-Type: application/json
//   X-Roovet-Signature: t=1762782800,v1=d4b5894731d8d8dbbe35cdd434ae6401 (format: t=...,v1=...)
//   X-Roovet-Timestamp: (inside signature "t=")
Verify (your app)
$raw = file_get_contents("php://input");
$sig = $_SERVER["HTTP_X_ROOVET_SIGNATURE"] ?? "";
$ok  = \App\Libraries\WebhookSigner::verify($raw, $sig, $theirSecret);
if (!$ok) { http_response_code(400); exit; }
Verify playground (demo)
Do not paste production secrets.
Algorithm: HMAC-SHA256 over t + '.' + raw.

Errors

Copy link

We use standard HTTP codes and a consistent error body:

Error shape
{
  "error": {
    "type": "insufficient_scope",
    "code": "403",
    "message": "Missing scope: wallet:read",
    "param": "scope"
  }
}
400 Bad Request
Validation or malformed JSON.
401 Unauthorized
Missing/invalid API key.
403 Insufficient Scope
Key lacks required scope.
404 Not Found
Unknown endpoint or resource.
409 Conflict
Idempotency or state conflict.
429 Too Many Requests
Rate limit exceeded.

Pagination & Idempotency

Copy link
Cursor Pagination

Use limit (1–100) and starting_after/ending_before.

GET /api/wallet/transactions?limit=50&starting_after=txn_123
Idempotency (POST/PUT)

Provide Idempotency-Key for safely retrying writes (dedupe window ≈ 24h).

POST /api/wallet/transfer
Idempotency-Key: 5b0d...d4
Now playing