Skip to content

HTTP API

Base URL: https://dayprotocol.com/api/v1
Auth: X-API-Key: <your-key>
OpenAPI: openapi.json
SDK: npm install github:dayprotocol/sdk

Related: API reference · Integration contract · Route catalog


Terminal window
export BASE=https://dayprotocol.com/api/v1
export KEY=$DAY_OWNER_API_KEY
export WALLET=0xYOUR_WALLET
# Status
curl -sS "$BASE/day/status" | jq .
# Strategies
curl -sS "$BASE/day/strategies" | jq '.strategies[:3]'
# Deposit plan (prepare only — you sign)
curl -sS -X POST "$BASE/day/strategies/deposit/plan" \
-H 'content-type: application/json' \
-d '{"strategyId":"suilend","amountMicros":"1000000"}' | jq .
# Position
curl -sS -H "X-API-Key: $KEY" "$BASE/wallets/$WALLET/position" | jq .
import { DayClient } from "@dayprotocol/sdk";
const day = new DayClient({
baseUrl: "https://dayprotocol.com",
apiKey: process.env.DAY_OWNER_API_KEY,
});
await day.readiness();
await day.listStrategies();
await day.prepareStrategyDeposit({ strategyId: "suilend", amountMicros: "1000000" });
await day.getPosition(process.env.DAY_WALLET_ADDRESS!);

TopicRule
AuthX-API-Key only. Do not send X-Role — it is ignored.
RolesKey maps to owner, agent, or keeper.
strategyIdBare id: suilend, navi, kamino. Not suilend-sui-usdc.
AmountsInteger micros strings ("1000000" = 1 USDC). No floats.
Fees0 on principal. All rates: Fees · live: GET /api/v1/day/fees.
WritesPlans are prepare-only until the owner signs. ownerMustSign: true, submitted: false unless a real on-chain digest exists.
APY / yieldLive value or null — never invented.
Money paths/api/v1/wallets/{address}/…
Public paths/api/v1/day/…

From GET /api/v1/day/venues (and status):

ModeMeaning
disabledPlans still prepare; nothing is broadcast by the server
owner_sign_prepareOwner signs; server does not broadcast
broadcastServer may submit only when env allows and a real digest exists

Phase-1 execution homes: Sui + Solana. Base / Arbitrum are discovery / prepare until write is live.


X-API-Key: <your-key>
RoleCan do
ownerRoute, withdraw, policy, bridge rescue
agentRead position / portfolio / preview (scoped to allowed wallets)
keeperHarvest batch, ops health
publicStatus, venues, strategies, deposit plans, balances
HTTPCodeWhen
401INVALID_API_KEYKey unknown
403UNAUTHORIZEDMissing key or wrong role
403WALLET_SCOPEKey not allowed for that wallet

MethodPathAuthWhat it does
GET/day/statuspublicPhase, fees, execution flags
GET/day/venuespublicVenues + readiness + optional live APY (?live=1)
GET/day/strategiespublicStrategies (venues + DAY Autopilot)
GET/day/strategies/{id}publicOne strategy
GET/day/venues/apypublicAPY table (null if unavailable)
GET/day/discoverpublicMarket map (not execution truth)
GET/day/errorspublicError catalog
GET/day/packagespublicOn-chain package ids
GET/openapi.jsonpublicOpenAPI 3.1

Deposit planPOST /day/strategies/deposit/plan · public

{ "strategyId": "suilend", "amountMicros": "1000000", "owner": "0x…" }
{
"status": "prepared",
"submitted": false,
"ownerMustSign": true,
"feeMicros": "0",
"strategyId": "suilend",
"amountMicros": "1000000"
}

Withdraw planPOST /day/strategies/withdraw/plan · public
Same id rules; principal fee 0.

Optional execute (owner-signed bytes only — never private keys):
POST /day/strategies/deposit/execute.

MethodPathAuthWhat it does
GET/wallets/{address}/positionowner | agentLiquid / staked / by chain
GET/wallets/{address}/portfolioowner | agentBalances + venues
GET/wallets/{address}/performanceowner | agentRealized yield / APY (null if unknown)
POST/wallets/{address}/previewowner | agentDry-run route (no mutation)
POST/wallets/{address}/routeownerCredit liquid (optional stake)
POST/wallets/{address}/harvestpermissionlessClaim yield; profit fee 1%/$10 (currently off)
POST/wallets/{address}/withdrawownerExit principal (fee 0)
POST/wallets/{address}/auto-payownerResidual yield → payees
POST/wallets/batch/positionsowner | agentUp to 50 wallets

Route example

{ "amountMicros": "1000000", "token": "USDC", "stake": false, "chain": "sui" }

Harvest

SituationResult
Nothing stakedmode: "no_op_harvest", gross "0"
Yield unavailablegross "0", reason set
Real yieldnet + compound (profit fee 1%/$10 currently off)
MethodPathNotes
POST/day/bridge/planCross-chain plan; owner signs
POST/day/bridge/rescueFailed bridge → owner only destination
POST/day/bridge/deliveryCredit only after confirmed delivery
POST/day/jupiter/planSolana swap
POST/day/turbos/planSui swap
POST/day/evm/swap/planBase / Arb (prepare until live)
POST/day/gas-sponsor/planGas sizing

Bridge plan needs source/dest chain, amount, and both addresses. Failed delivery never redirects away from the owner.

MethodPathAuth
GET/wallets/{address}/autopilotowner | agent
GET/wallets/{address}/autopilot/historyowner | agent
POST/wallets/{address}/autopilot/enableowner
POST/wallets/{address}/autopilot/disableowner
POST/wallets/{address}/autopilot/previewowner | agent
POST/wallets/{address}/autopilot/tickowner | agent
POST/wallets/{address}/autopilot/decideowner | agent

Autopilot is within-chain only. Cross-chain moves use an explicit bridge plan — never a silent rebalance.

Featured strategy: day-autopilot-top-30d-monthly — monthly re-rank to top 30d APY; switches only if the challenger is ≥7 percentage points better; fees: see Fees.


Terminal window
BASE=https://dayprotocol.com/api/v1
KEY=$DAY_OWNER_API_KEY
WALLET=walkthrough-1
# 1. Pick a strategy
curl -sS "$BASE/day/strategies" | jq '.strategies[] | select(.strategyId=="suilend")'
# 2. Preview (no chain submit)
curl -sS -X POST -H "X-API-Key: $KEY" -H 'content-type: application/json' \
-d '{"amountMicros":"1000000","stake":false}' \
"$BASE/wallets/$WALLET/preview" | jq .
# 3. Route (credit liquid)
curl -sS -X POST -H "X-API-Key: $KEY" -H 'content-type: application/json' \
-H "Idempotency-Key: oy_route_${WALLET}_1" \
-d '{"amountMicros":"1000000","token":"USDC","stake":false,"chain":"sui"}' \
"$BASE/wallets/$WALLET/route" | jq .
# 4. Position
curl -sS -H "X-API-Key: $KEY" "$BASE/wallets/$WALLET/position" | jq '{liquidMicros,stakedMicros}'
# 5. Venue deposit plan (owner signs offline)
curl -sS -X POST -H 'content-type: application/json' \
-d '{"strategyId":"suilend","amountMicros":"1000000"}' \
"$BASE/day/strategies/deposit/plan" | jq '{status,ownerMustSign,submitted,feeMicros}'
# 6. Harvest (no stake → no_op)
curl -sS -X POST -H "X-API-Key: $KEY" -H 'content-type: application/json' \
-d '{"execute":true}' \
"$BASE/wallets/$WALLET/harvest" | jq '{mode,reason,grossYieldMicros,protocolFeeMicros}'
# 7. Withdraw principal
curl -sS -X POST -H "X-API-Key: $KEY" -H 'content-type: application/json' \
-d '{"amountMicros":"1000000"}' \
"$BASE/wallets/$WALLET/withdraw" | jq .

Expect: route/withdraw fee 0. Harvest fee: see Fees.


ActionFee
Deposit / route / withdraw principal0
Harvest realized yield (profit fee)1% (100 bps), cap $10 — currently off
Swap plan (Jupiter / Turbos / EVM)DAY swap fee (see Fees) + pool fee (disclosed)
Bridge planDAY bridge fee (see Fees) + rail fee (disclosed)

With the profit fee currently disabled, gross yield 20000 micros → net 20000. Rates and status: Fees.


{ "code": "UNAUTHORIZED", "message": "owner required" }
CodeHTTPMeaning
UNAUTHORIZED403Missing or wrong role
INVALID_API_KEY401Unknown key
WALLET_SCOPE403Wallet not allowed for this key
NOT_FOUND404Unknown strategy or route
RATE_LIMITED429Slow down

Many plan endpoints return HTTP 200 with status: "blocked" and blockers: [...] — always check the body, not only the status code.


MethodHTTP
readinessGET /day/status
listVenues / listStrategiesGET /day/venues · /day/strategies
getStrategyGET /day/strategies/{id}
prepareStrategyDeposit / prepareStrategyWithdrawPOST …/plan
getPositionGET /wallets/{address}/position
previewRoute / routeYieldPOST preview · route
harvest / withdraw / enableAutoPaymoney posts
bridgePlan / bridgeRescuePlanbridge
const day = new DayClient({
baseUrl: "https://dayprotocol.com", // origin only — SDK adds /api/v1
apiKey: process.env.DAY_OWNER_API_KEY,
});