Rewards-as-a-Service
Developer Docs
Integrate tokenised loyalty rewards into any fintech product in hours. Issue PLUS tokens on-chain, connect to 500+ global redemption brands, and deliver USDC staking yield — all via a single REST API.
How RaaS works end-to-end
Authentication
All API requests must be authenticated with your partner API key passed in the Authorization header. Keys are environment-scoped — a sandbox key never touches production.
Authorization: Bearer pm_live_xxxxxxxxxxxxxxxx on every request. Never expose keys client-side.Base URL & Versioning
The API is versioned in the URL path. The current stable version is v2. We maintain backward compatibility within a major version and give 90 days notice before deprecating any endpoint.
| Environment | Base URL | Key Prefix |
|---|---|---|
| Production | https://api.plusmore.xyz/v2 | pm_live_ |
| Sandbox | https://sandbox.api.plusmore.xyz/v2 | pm_test_ |
Test before you ship
Full production parity. Use test PLUS tokens, mock card transactions, and webhook delivery testing. Free with no rate limits in sandbox.
PLUS Issuance
PLUS issuance is the core RaaS flow. When a user makes a qualifying purchase via a partner card or platform, you call the issuance endpoint to mint and deliver PLUS tokens to their wallet. Tokens are funded from your pre-loaded partner pool — no new supply is created at issuance.
| Concept | Description |
|---|---|
| partner_pool | Your pre-funded PLUS balance. Must be topped up before issuance calls will succeed. |
| wallet_address | The user's Base-compatible wallet. PLUS settles here instantly on confirmation. |
| reward_rate | PLUS per USD spent. Configurable per merchant or global. Default set in partner dashboard. |
| transaction_id | Your unique reference. Prevents duplicate issuance — idempotency is enforced by this field. |
Request body
| Parameter | Type | Description |
|---|---|---|
| wallet_addressrequired | string | Recipient's Base wallet address (0x…) |
| amount_usdrequired | number | Transaction value in USD. PLUS is calculated from your configured reward rate. |
| transaction_idrequired | string | Your unique transaction reference. Used for idempotency — duplicate IDs are rejected with 409. |
| merchant_idoptional | string | Override the reward rate for a specific merchant. Defaults to your global partner rate. |
| metadataoptional | object | Arbitrary key-value pairs stored against the issuance for your records (max 10 keys). |
Example request
Response
Send up to 500 issuances in a single request. Each item follows the same schema as a single issuance. Partial success is supported — failed items return per-item errors while successful ones confirm immediately.
Returns the full issuance object including on-chain confirmation status. Useful for polling if your webhook delivery was delayed.
| Status value | Meaning |
|---|---|
| pending | Submitted to Base, awaiting block confirmation (usually <5 seconds) |
| confirmed | On-chain and settled to user wallet |
| failed | Rejected — check failure_reason in response |
Redemption
PLUS holders can exchange tokens for real-world rewards via our 500+ brand catalogue. Redemptions are funded entirely by merchant margin — no new tokens are minted, keeping PLUS non-inflationary. The API handles fulfilment; your UI simply calls the endpoint.
Returns paginated catalogue of redeemable items. Filter by category, region, or search by brand name.
| Query param | Type | Description |
|---|---|---|
| categoryoptional | string | gift_card · cashback · subscription · travel |
| regionoptional | string | ISO 3166-1 alpha-2. Filters brands available in that market. |
| searchoptional | string | Brand name full-text search (e.g. amazon) |
| pageoptional | integer | Page number, default 1. Page size is 50. |
| Parameter | Type | Description |
|---|---|---|
| wallet_addressrequired | string | Wallet holding the PLUS to be redeemed |
| item_idrequired | string | Catalogue item ID from GET /catalogue |
| quantityoptional | integer | Number of units to redeem. Default 1. |
| delivery_emailoptional | string | For gift cards, the email to deliver the code to. Defaults to user's registered email. |
Staking
Partners can expose PLUS staking directly within their product UI. Users lock PLUS for a chosen duration and earn USDC rewards paid from merchant-funded pools. Yield is calculated on the USD value locked at time of staking — predictable from day one.
| Parameter | Type | Description |
|---|---|---|
| wallet_addressrequired | string | Wallet staking the PLUS |
| plus_amountrequired | number | Amount of PLUS to stake |
| tierrequired | string | flex · 3m · 6m · 12m |
| auto_compoundoptional | boolean | Enable Auto Buyback compounding. Default false. |
Returns full position details including accrued USDC rewards to date, days remaining, and early withdrawal penalty if applicable.
User & Wallet
PlusMore accounts are non-custodial. Basic earning and staking requires no KYC — users are registered as Plutus Lite accounts automatically. Full KYC unlocks fiat redemptions and higher transaction limits.
| Parameter | Type | Description |
|---|---|---|
| wallet_addressrequired | string | User's Base wallet address |
| emailoptional | string | Required for gift card and cashback delivery |
| external_user_idoptional | string | Your internal user ID for cross-referencing |
| regionoptional | string | ISO 3166-1 alpha-2. Sets catalogue defaults. |
Webhooks
PlusMore sends signed POST requests to your registered endpoint for all key platform events. Verify the X-PlusMore-Signature header using your webhook secret to ensure authenticity.
Event types
Error Codes
All errors follow a consistent JSON shape with a machine-readable error code, human-readable message, and a request_id for support escalation.
Request body is malformed or a required field is absent/invalid.
API key missing, invalid, or revoked. Check your Authorization header.
Your partner pool balance is too low to cover this issuance. Top up via the Partner Dashboard.
This redemption requires the user to have completed full KYC. Direct them to the PlusMore KYC flow.
Resource not found — check the ID in the path parameter.
transaction_id has already been processed. The existing issuance ID is returned.
Too many requests. Check the Retry-After header. See rate limits below.
Rate Limits
Limits are enforced per partner API key. Batch endpoints count as one request regardless of items. Sandbox has no rate limits.
| Endpoint group | Limit | Window |
|---|---|---|
| /v2/rewards/issue | 1,000 requests | Per minute |
| /v2/rewards/issue/batch | 50 requests | Per minute |
| /v2/redemption/* | 500 requests | Per minute |
| /v2/staking/* | 300 requests | Per minute |
| /v2/users/* | 500 requests | Per minute |
| All other endpoints | 1,000 requests | Per minute |
Changelog
| Version | Date | Changes |
|---|---|---|
| v2.1.0 | 2025-03-01 | Added batch issuance endpoint. Auto Buyback flag on staking. plus_staked field on balance response. |
| v2.0.0 | 2025-01-15 | Major version — Base L2 migration. Staking tiers restructured. Webhook signature verification added. v1 deprecated (EOL 2025-07-15). |
| v1.4.2 | 2024-11-10 | Catalogue region filtering. KYC status on user object. Rate limit headers standardised. |