Overview
Earn is exposed as a single product called Auto-Earn. You don’t allocate balances per strategy — you flip a per-yield-source switch for the user and Payward picks strategies and routes eligible balances. Payward absorbs any on-chain bonding or unbonding periods, so allocated assets stay liquid and remain at the user’s disposal at all times. The supported yield sources arestaking and base_rewards; more may be added without breaking the response shape.
The integration shape is six endpoints:
If you have used Kraken’s Spot REST Earn endpoints
(
Strategies, Allocations, Allocate, Deallocate), the PWS Earn API is a higher-level abstraction of the same
product. PWS picks strategies, routes eligible balances, and hides any on-chain bonding or unbonding so allocated
assets remain liquid for the user. You see the result through the six endpoints above and through the Portfolio API,
which surfaces each settled reward as an earn_reward transaction.Prerequisites
- Payward Services API credentials (see the Authentication guide).
- A verified user with at least one account and sufficient balance in the source asset.
- Examples target
https://api.services.payward.comand read credentials from thePWS_API_KEYandPWS_API_SECRETenvironment variables.
Workflow
1
Discover Auto-Earn assets (optional, pre-account)
Show what’s available in a country before you have an account. User-agnostic.
GET /v1/earn/auto/assets?country=US2
Discover Auto-Earn assets for an account
Show APY and per-user allocation cap for the account’s eligible assets.
GET /v1/accounts/{account_id}/earn/auto/assets3
Set Auto-Earn preferences
Enable or disable a yield source. Async.
PATCH /v1/accounts/{account_id}/earn/auto4
Poll until preferences settle
Read current preferences and watch
pending_enabled / pending_disabled resolve.GET /v1/accounts/{account_id}/earn/auto5
Read allocations and rewards
Show how much is currently earning, and historical / upcoming rewards.
GET /v1/accounts/{account_id}/earn/auto/allocationsGET /v1/accounts/{account_id}/earn/auto/rewards
Auto-Earn preference lifecycle
Each yield source has one of four states. Only the yield sources the user is eligible for appear inGET /v1/accounts/{account_id}/earn/auto; missing fields mean the user can’t enable that source today and the corresponding field on PATCH is a no-op. There is no separate eligibility endpoint — presence in this response is the eligibility check.
PATCH /v1/accounts/{account_id}/earn/auto returns immediately with an empty body. Poll GET /v1/accounts/{account_id}/earn/auto until the pending state resolves.
Asset, amount, and quote-currency conventions
Allocation and reward entries describe an asset at the top level using three fields:
All monetary fields inside an entry are plain decimal strings:
The allocations and rewards endpoints accept
quote_symbol and quote_type to choose the quote asset, and echo both at the top level of the response so you can format *_in_quote values without re-stating the choice. Today only quote_type=fiat is supported; quote_symbol defaults to USD. Pass the same values across Earn and the Portfolio API so totals reconcile.
Authentication setup
Authenticated endpoints require an HMAC-SHA512 request signature in theAPI-Sign header and a monotonically increasing nonce in the API-Nonce header. The helper below derives the signature from the URL path, request body, and nonce. See the Authentication guide for the full algorithm.
Every PWS write endpoint (
POST / PUT / DELETE) accepts an Idempotency-Key header containing a UUIDv4. Generate
a fresh key per logical attempt — replays of the same key return the original response body and the
Idempotent-Replayed: true response header, which keeps retries safe under timeouts and connection drops.params argument.
Step 1: discover Auto-Earn assets by country
GET /v1/earn/auto/assets is user-agnostic. Use it to surface the value proposition before sign-up — for example on a landing page filtered by the visitor’s country. Pagination is via page_token / page_size.
Response example
Step 2: discover Auto-Earn assets for an account
GET /v1/accounts/{account_id}/earn/auto/assets returns the same shape as Step 1 but scoped to a specific account. Use it after sign-up to confirm exactly what that account can auto-earn.
Response example
Step 3: set Auto-Earn preferences
Send aPATCH to /v1/accounts/{account_id}/earn/auto with the desired state of each yield source you want to change. All body fields are optional — yield sources you omit keep their current preference, so you can flip a single source without touching the others.
Supported yield sources: staking, base_rewards. Allowed values: "enabled", "disabled".
Response example
The
200 OK confirms the preference change was accepted, not that every eligible balance is already earning.
Provisioning runs asynchronously; observe pending_enabled / pending_disabled on GET /v1/accounts/{account_id} /earn/auto to know when the change has settled. A second PATCH issued before the pending state resolves returns
409 Conflict — see the preference lifecycle above.Step 4: poll until preferences settle
GET /v1/accounts/{account_id}/earn/auto returns the current preference for every yield source the user is eligible for. Eligibility is country-aware: if a user moves to a region where staking isn’t supported, the staking field disappears from this response and the corresponding field on PATCH becomes a no-op.
Response example
Step 5a: list current allocations
GET /v1/accounts/{account_id}/earn/auto/allocations returns the user’s current per-asset allocation, plus the all-asset total in the requested quote currency. The endpoint is cursor-paginated; next_page_token is absent on the last page. All amounts inside entries are plain decimal strings; the response echoes quote_symbol / quote_type at the top level so you know how to format *_in_quote values.
Response example
Auto-Earn allocations are liquid. The
allocated amount is the user’s current earning balance and is always at the
user’s disposal — PWS absorbs any on-chain bonding or unbonding so there are no “in-transit” amounts for you to track
on the Earn side.Step 5b: list rewards
GET /v1/accounts/{account_id}/earn/auto/rewards returns historical rewards per asset, the all-time total in the quote currency, and the next payout estimate. Same quote_symbol / quote_type / page_token / page_size semantics as allocations, and the same envelope (quote_symbol / quote_type echoed at the top level).
estimated_next_reward, estimated_next_reward_in_quote, and the top-level next_reward_date are absent when no reward is pending. other_assets is absent on an entry when every reward for that asset was paid in the entry’s own asset.
Response example
Reward amounts can be very small for low-APY assets — a value like
"0.00000001" is common. Decide up front how to
render near-zero values (for example, “<0.00000001 ETH” or “~0”).Reconciling rewards in Portfolio
When a payout settles, it appears in the Portfolio activity feed as anearn_reward transaction:
Error handling
All error responses share a standard envelope:Best practices
- Treat the
PATCHas eventually consistent. A200 OKconfirms the change was accepted, not that balances are already earning. - Only one preference change in flight per account. Wait for the pending state to resolve before submitting another change; otherwise the second
PATCHreturns409 Conflict. - Only send the yield sources you actually want to change. Omit the others to keep their preferences untouched.
- Pass
quote_symbolconsistently across allocations, rewards, and Portfolio so converted totals line up across views. - Don’t assume APY is fixed. Refetch the asset list whenever you display APY; it drifts with network conditions and country availability.
- Capture
Request-Idfrom response headers. It speeds up support investigations.