No SDK, no dependency, no build step. One base URL, one auth header, JSON in and out. Here is the whole thing — from a test key to a real reward — in the time it takes to read this page.
Sign up at sendreward.com and open API keys. Every account comes with a test key and $1,000 of free sandbox balance. The key is shown once, so copy it somewhere safe. It starts with sr_test_.
Test rewards behave exactly like live ones — identical responses, identical statuses, identical webhooks — except nothing is emailed and nothing is charged. Build your entire integration against the test key, then swap it for a live key when you are ready.
The whole API is one base URL:
https://sendreward.com/api/v1
Send a reward with a single POST. The Idempotency-Key header is optional but you should always send one — it makes retries safe.
curl https://sendreward.com/api/v1/rewards \ -H "Authorization: Bearer sr_test_…" \ -H "Idempotency-Key: order-88213" \ -H "Content-Type: application/json" \ -d '{ "recipient_email": "maria@example.com", "recipient_name": "Maria", "amount": 25, "reference": "order-88213", "message": "Thanks for your order, Maria — here is a little something extra." }'
You get back 201 Created and the reward object:
{
"id": "rw_7f3a2c91d0e84b16",
"object": "reward",
"mode": "test",
"status": "sent",
"amount": "25.00",
"currency": "USD",
"recipient_email": "maria@example.com",
"reference": "order-88213",
"created_at": "2026-10-19T14:02:11Z"
}
That is a reward sent. In test mode it landed in your dashboard under the Test filter; in live mode Maria just got an email.
There is no SDK to install, so it is a handful of lines anywhere. These all do exactly what the curl above does.
$ch = curl_init('https://sendreward.com/api/v1/rewards'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . $apiKey, 'Idempotency-Key: ' . $orderId, 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode([ 'recipient_email' => $email, 'amount' => 25, 'reference' => $orderId, 'message' => 'Thanks for your order!', ]), ]); $reward = json_decode(curl_exec($ch), true); curl_close($ch);
const res = await fetch('https://sendreward.com/api/v1/rewards', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Idempotency-Key': orderId, 'Content-Type': 'application/json', }, body: JSON.stringify({ recipient_email: email, amount: 25, reference: orderId, message: 'Thanks for your order!', }), }); const reward = await res.json();
import requests reward = requests.post( "https://sendreward.com/api/v1/rewards", headers={ "Authorization": f"Bearer {api_key}", "Idempotency-Key": order_id, }, json={ "recipient_email": email, "amount": 25, "reference": order_id, "message": "Thanks for your order!", }, timeout=15, ).json()
One GET, and it tells you what you have to spend. This is also a good health check for your key.
curl https://sendreward.com/api/v1/balance \ -H "Authorization: Bearer sr_test_…" { "object": "balance", "mode": "test", "available": "1000.00", "currency": "USD" }
If a send would overdraw your balance you get 402 insufficient_balance and nothing is sent — so you can check first, or just handle the error.
Add an HTTPS endpoint under Notifications and SendReward will POST you a signed event on every status change: reward.sent, reward.delivered, reward.redeemed, reward.failed, reward.canceled. Verify the X-SendReward-Signature header with your endpoint secret, and handle events idempotently by their id — the same event can arrive twice. The signature verification snippets are in the reference.
When your integration works against the test key, create a live key in the dashboard, fund your balance (bank transfer is free), and swap the key string. Nothing else changes — the request shape, the response, the statuses and the webhooks are identical. That is the whole migration.
Retry safely. On any timeout or 500, retry with the same Idempotency-Key. You will either get the original reward back (with Idempotent-Replayed: true) or a clean new one — never a silent double charge.
No. SendReward is a plain REST API — one base URL, one auth header, JSON in and out. There is nothing to install, so any language that can make an HTTPS request works. Copy the snippet below and go.
Every account starts with a test key (sr_test_…) and $1,000 of free sandbox balance. Test rewards behave exactly like live ones — same responses, same statuses, same webhooks — but nothing is emailed and nothing is charged. When you are ready, create a live key and swap the string.
The mode is in the key itself. sr_test_ spends sandbox balance and sends nothing; sr_live_ spends your real balance and emails a real gift card. There is no separate flag to set.
Send an Idempotency-Key header with a value unique to that reward — an order number, a user ID plus event name, a claim ID. If the same key arrives again, you get the original reward back and nothing new is sent. See preventing duplicate rewards.
Add an HTTPS webhook endpoint in the dashboard and SendReward will POST you a signed event on every status change — sent, delivered, redeemed, failed, canceled. Verify the signature with the endpoint secret.
Nothing beyond face value. There is no platform fee and no per-reward fee; you pay the face value of each card. Bank funding is free, card funding is 3% + $0.30.
Free account, $1,000 sandbox balance, no SDK, no sales call.