Give stock
curl --request POST \
--url https://api.stockly.com/v1/rewards \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"userId": "6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"idempotencyKey": "order-1001-reward",
"amountUsd": 5.25,
"assetSymbol": "AAPL",
"source": "cashback",
"metadata": {
"orderId": "1001"
}
}
'import requests
url = "https://api.stockly.com/v1/rewards"
payload = {
"userId": "6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"idempotencyKey": "order-1001-reward",
"amountUsd": 5.25,
"assetSymbol": "AAPL",
"source": "cashback",
"metadata": { "orderId": "1001" }
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
userId: '6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7',
idempotencyKey: 'order-1001-reward',
amountUsd: 5.25,
assetSymbol: 'AAPL',
source: 'cashback',
metadata: {orderId: '1001'}
})
};
fetch('https://api.stockly.com/v1/rewards', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.stockly.com/v1/rewards",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'userId' => '6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7',
'idempotencyKey' => 'order-1001-reward',
'amountUsd' => 5.25,
'assetSymbol' => 'AAPL',
'source' => 'cashback',
'metadata' => [
'orderId' => '1001'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.stockly.com/v1/rewards"
payload := strings.NewReader("{\n \"userId\": \"6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7\",\n \"idempotencyKey\": \"order-1001-reward\",\n \"amountUsd\": 5.25,\n \"assetSymbol\": \"AAPL\",\n \"source\": \"cashback\",\n \"metadata\": {\n \"orderId\": \"1001\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.stockly.com/v1/rewards")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"userId\": \"6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7\",\n \"idempotencyKey\": \"order-1001-reward\",\n \"amountUsd\": 5.25,\n \"assetSymbol\": \"AAPL\",\n \"source\": \"cashback\",\n \"metadata\": {\n \"orderId\": \"1001\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.stockly.com/v1/rewards")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"userId\": \"6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7\",\n \"idempotencyKey\": \"order-1001-reward\",\n \"amountUsd\": 5.25,\n \"assetSymbol\": \"AAPL\",\n \"source\": \"cashback\",\n \"metadata\": {\n \"orderId\": \"1001\"\n }\n}"
response = http.request(request)
puts response.read_body{
"reward": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"appId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"userId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"idempotencyKey": "<string>",
"amountUsd": 123,
"assetSymbol": "<string>",
"source": "<string>",
"metadata": {},
"createdAt": "2023-11-07T05:31:56Z",
"executedAt": "2023-11-07T05:31:56Z",
"failureReason": "<string>"
},
"status": "<string>",
"idempotentReplay": true
}{
"reward": {
"id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
"appId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"userId": "6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"idempotencyKey": "order-1001-reward",
"amountUsd": 5.25,
"assetSymbol": "AAPL",
"source": "cashback",
"metadata": {
"orderId": "1001"
},
"status": "recorded",
"createdAt": "2026-06-13T12:00:00.000Z",
"executedAt": null,
"failureReason": null
},
"status": "recorded",
"idempotentReplay": false
}{
"error": {
"code": "conflict",
"message": "idempotencyKey was already used with a different payload",
"details": {
"idempotencyKey": "order-1001-reward"
},
"requestId": "f0e1d2c3-4b5a-6789-0abc-def012345678"
}
}{
"error": {
"code": "conflict",
"message": "idempotencyKey was already used with a different payload",
"details": {
"idempotencyKey": "order-1001-reward"
},
"requestId": "f0e1d2c3-4b5a-6789-0abc-def012345678"
}
}{
"error": {
"code": "conflict",
"message": "idempotencyKey was already used with a different payload",
"details": {
"idempotencyKey": "order-1001-reward"
},
"requestId": "f0e1d2c3-4b5a-6789-0abc-def012345678"
}
}{
"error": {
"code": "conflict",
"message": "idempotencyKey was already used with a different payload",
"details": {
"idempotencyKey": "order-1001-reward"
},
"requestId": "f0e1d2c3-4b5a-6789-0abc-def012345678"
}
}Stock awards
Give stock
Gives a user stock by recording a stock award. The award is created with status recorded; Stockly then fulfills it and the stock appears in the user’s portfolio. idempotencyKey makes this safe to retry: replaying the same request returns the original award with idempotentReplay: true and creates no duplicate. Reusing a key with a different payload returns 409.
POST
/
v1
/
rewards
Give stock
curl --request POST \
--url https://api.stockly.com/v1/rewards \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"userId": "6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"idempotencyKey": "order-1001-reward",
"amountUsd": 5.25,
"assetSymbol": "AAPL",
"source": "cashback",
"metadata": {
"orderId": "1001"
}
}
'import requests
url = "https://api.stockly.com/v1/rewards"
payload = {
"userId": "6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"idempotencyKey": "order-1001-reward",
"amountUsd": 5.25,
"assetSymbol": "AAPL",
"source": "cashback",
"metadata": { "orderId": "1001" }
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
userId: '6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7',
idempotencyKey: 'order-1001-reward',
amountUsd: 5.25,
assetSymbol: 'AAPL',
source: 'cashback',
metadata: {orderId: '1001'}
})
};
fetch('https://api.stockly.com/v1/rewards', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.stockly.com/v1/rewards",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'userId' => '6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7',
'idempotencyKey' => 'order-1001-reward',
'amountUsd' => 5.25,
'assetSymbol' => 'AAPL',
'source' => 'cashback',
'metadata' => [
'orderId' => '1001'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.stockly.com/v1/rewards"
payload := strings.NewReader("{\n \"userId\": \"6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7\",\n \"idempotencyKey\": \"order-1001-reward\",\n \"amountUsd\": 5.25,\n \"assetSymbol\": \"AAPL\",\n \"source\": \"cashback\",\n \"metadata\": {\n \"orderId\": \"1001\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.stockly.com/v1/rewards")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"userId\": \"6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7\",\n \"idempotencyKey\": \"order-1001-reward\",\n \"amountUsd\": 5.25,\n \"assetSymbol\": \"AAPL\",\n \"source\": \"cashback\",\n \"metadata\": {\n \"orderId\": \"1001\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.stockly.com/v1/rewards")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"userId\": \"6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7\",\n \"idempotencyKey\": \"order-1001-reward\",\n \"amountUsd\": 5.25,\n \"assetSymbol\": \"AAPL\",\n \"source\": \"cashback\",\n \"metadata\": {\n \"orderId\": \"1001\"\n }\n}"
response = http.request(request)
puts response.read_body{
"reward": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"appId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"userId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"idempotencyKey": "<string>",
"amountUsd": 123,
"assetSymbol": "<string>",
"source": "<string>",
"metadata": {},
"createdAt": "2023-11-07T05:31:56Z",
"executedAt": "2023-11-07T05:31:56Z",
"failureReason": "<string>"
},
"status": "<string>",
"idempotentReplay": true
}{
"reward": {
"id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
"appId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"userId": "6f1d2a3b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"idempotencyKey": "order-1001-reward",
"amountUsd": 5.25,
"assetSymbol": "AAPL",
"source": "cashback",
"metadata": {
"orderId": "1001"
},
"status": "recorded",
"createdAt": "2026-06-13T12:00:00.000Z",
"executedAt": null,
"failureReason": null
},
"status": "recorded",
"idempotentReplay": false
}{
"error": {
"code": "conflict",
"message": "idempotencyKey was already used with a different payload",
"details": {
"idempotencyKey": "order-1001-reward"
},
"requestId": "f0e1d2c3-4b5a-6789-0abc-def012345678"
}
}{
"error": {
"code": "conflict",
"message": "idempotencyKey was already used with a different payload",
"details": {
"idempotencyKey": "order-1001-reward"
},
"requestId": "f0e1d2c3-4b5a-6789-0abc-def012345678"
}
}{
"error": {
"code": "conflict",
"message": "idempotencyKey was already used with a different payload",
"details": {
"idempotencyKey": "order-1001-reward"
},
"requestId": "f0e1d2c3-4b5a-6789-0abc-def012345678"
}
}{
"error": {
"code": "conflict",
"message": "idempotencyKey was already used with a different payload",
"details": {
"idempotencyKey": "order-1001-reward"
},
"requestId": "f0e1d2c3-4b5a-6789-0abc-def012345678"
}
}Authorizations
Your Stockly API key. Identifies your app; you never pass an app id.
Body
application/json
Must reference an existing user in your app.
Unique per logical award. Safe to retry.
Required string length:
8 - 128Award value in USD.
Required range:
x <= 1000000Stock ticker from the catalog, e.g. AAPL. Normalized to uppercase.
Required string length:
1 - 16Example:
"AAPL"
Optional label, e.g. cashback.
Required string length:
1 - 64Optional arbitrary JSON, returned on reads.
⌘I