Skip to content

Agent API

Integration contract (DAY-291/292): 41-integration-contract.md · Full route table: 44-route-catalog.md · OpenAPI: /api/v1/openapi.json API series: v1 · version: 1.0.0 · DAY-280
Preferred base: https://dayprotocol.com/api/v1
Legacy (still works): https://dayprotocol.com/api/v1/day/*
OpenAPI: https://dayprotocol.com/api/v1/openapi.json (also /openapi.json)
SDK: npm install github:dayprotocol/sdk · package @dayprotocol/sdk
Docs site: https://docs.dayprotocol.com

Machine source of truth for paths + auth = api/routes-manifest.mjs.
OpenAPI is generated from that manifest (runtime/config/openapi.mjs). CI fails if docs drift.

Under /api/v1, paths mirror the unversioned table:
/api/v1/day/status/api/day/status, /api/v1/wallets/{address}/position/api/v1/wallets/{address}/position.


FactDetail
Auth headerX-API-Key only for roles. X-Role is ignored (spoofable).
Rolesowner / agent / keeper from server allowlists (DAY_OWNER_API_KEYS, DAY_AGENT_API_KEYS, DAY_KEEPER_API_KEYS).
strategyIdBare venue id: suilend, navi, kamino, aave-v3. Not suilend-sui-usdc. form-suilend accepted as alias.
AmountsMicros strings ("1000000" = 1 USDC). Never floats.
Fees0 bps on principal (deposit/withdraw/route). 500 bps skim on yield only at harvest.
WritesReturn prepared plans. ownerMustSign: true, submitted: false unless broadcast env produces a real digest.
HarvestDoes not invent yield. No stake → mode: "no_op_harvest", reason: "no_staked_position".
IdentityWallet address only (DAY-294). Canonical money surface: /api/v1/wallets/{address}/*. No characters/accounts as first-class DAY concepts.

Execution modes (from GET /api/v1/day/venues)

Section titled “Execution modes (from GET /api/v1/day/venues)”
executionModeMeaning
disabledPlans still prepare; notes may include execution_disabled
owner_sign_prepareOPEN_YIELD_EXECUTION_ENABLED=1 — owner signs; no server broadcast
broadcastexecution + OPEN_YIELD_ALLOW_BROADCAST=1 — server may submit only with real digest

X-API-Key: <your-key>
RoleEnv allowlistTypical use
ownerDAY_OWNER_API_KEYSMutations: route, withdraw, auto-pay, bridge rescue, set policy
agentDAY_AGENT_API_KEYSReads: position, preview, funding, GET auto-yield (wallet scope may apply)
keeperDAY_KEEPER_API_KEYSSurvival, harvest batch, some refresh routes
public / permissionless(none)status, venues, strategies, harvest poke, deposit plan
HTTPWhen
401 INVALID_API_KEYKey present but not in any allowlist
403 UNAUTHORIZEDMissing key or wrong role
403 WALLET_SCOPEKey not allowed for this wallet address

SDK:

import { DayClient } from "@dayprotocol/sdk";
// baseUrl: origin OR https://dayprotocol.com/api/v1 — SDK never double-prefixes
const day = new DayClient({
baseUrl: "https://dayprotocol.com", // recommended: origin only
apiKey: process.env.DAY_OWNER_API_KEY, // → X-API-Key
});

sessionToken (optional) sets Authorization: Bearer … for future session auth — not how owner roles work today. Do not document Bearer as the primary model.

Local/dev: day-dev-owner / day-dev-agent / day-dev-keeper only when DAY_AUTH_ALLOW_DEV_KEYS=1 and not production.


Terminal window
export DAY_KEY="$DAY_OWNER_API_KEY" # real owner key
export BASE=https://dayprotocol.com/api/v1 # preferred v1 prefix
export WALLET=0xYOUR_WALLET_OR_DEMO
# 1) status
curl -sS "$BASE/day/status" | jq '{phase,launchHomes,protocolYieldSkimBps,executionEnabled}'
# 2) strategies (bare ids)
curl -sS "$BASE/day/strategies" | jq '.strategies[:3] | .[] | {strategyId,chain,ready,grossApyBps}'
# 3) deposit plan (prepare-only, fee 0)
curl -sS -X POST "$BASE/day/strategies/deposit/plan" \
-H 'content-type: application/json' \
-d '{"strategyId":"suilend","amountMicros":"1000000"}' \
| jq '{status,ownerMustSign,submitted,feeMicros,executionMode}'
# 4) position (owner or agent key)
curl -sS -H "X-API-Key: $DAY_KEY" "$BASE/wallets/$WALLET/position" | jq .
import { DayClient } from "@dayprotocol/sdk";
// Either form works (SDK never double-prefixes /api/v1):
// baseUrl: "https://dayprotocol.com"
// baseUrl: "https://dayprotocol.com/api/v1"
const day = new DayClient({
baseUrl: "https://dayprotocol.com", // recommended: origin only
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 || "0xdemo");

3.1 GET /api/v1/day/status · public · SDK readiness()

Section titled “3.1 GET /api/v1/day/status · public · SDK readiness()”

No body. Returns phase, launchHomes, protocolYieldSkimBps (500), execution flags.

3.2 GET /api/v1/day/venues · public · SDK listVenues()

Section titled “3.2 GET /api/v1/day/venues · public · SDK listVenues()”

Query: ?chain=sui|solana|base|arbitrum, ?live=1 (optional live APY; fail-closed if live reader fails).

Success fields (top-level): executionMode, executionEnabled, broadcastEnabled, launchHomes, venues[] with venueId, ready, writeReady, gross_apy_bps, chain, liveYieldReader.

3.3 GET /api/v1/day/strategies · public · SDK listStrategies()

Section titled “3.3 GET /api/v1/day/strategies · public · SDK listStrategies()”

strategyId === venueId. Prefer over /forms for product UI.

3.4 GET /api/v1/day/strategies/{id} · public · SDK getStrategy(id)

Section titled “3.4 GET /api/v1/day/strategies/{id} · public · SDK getStrategy(id)”

id = suilend or form-suilend. Unknown → 404.

3.5 POST /api/v1/day/strategies/deposit/plan · public · SDK prepareStrategyDeposit

Section titled “3.5 POST /api/v1/day/strategies/deposit/plan · public · SDK prepareStrategyDeposit”
{ "strategyId": "suilend", "amountMicros": "1000000", "owner": "0x…", "autoYieldEnabled": true }
FieldTypeRequiredNotes
strategyIdstringyesbare venue id
amountMicrosstringyesmicros
ownerstringnooptional plan field
autoYieldEnabledbooleannodefault true for supply allow

Success example:

{
"schemaVersion": "day-strategy-deposit-plan.v1",
"status": "prepared",
"submitted": false,
"ownerMustSign": true,
"feeMicros": "0",
"protocolYieldSkimBps": 500,
"executionMode": "owner_sign_prepare",
"strategyId": "suilend",
"amountMicros": "1000000"
}

3.6 POST /api/v1/day/strategies/withdraw/plan · public · SDK prepareStrategyWithdraw

Section titled “3.6 POST /api/v1/day/strategies/withdraw/plan · public · SDK prepareStrategyWithdraw”

Same id rules; principal fee 0.

3.7 GET /api/v1/wallets/{address}/position · owner|agent · SDK getPosition

Section titled “3.7 GET /api/v1/wallets/{address}/position · owner|agent · SDK getPosition”
Terminal window
curl -sS -H "X-API-Key: $DAY_KEY" \
https://dayprotocol.com/api/v1/wallets/demo/position

200 body includes liquidMicros, stakedMicros, byChain, estimates, autoYieldEnabled.

3.7b GET /api/v1/wallets/{address}/portfolio · owner|agent · SDK getPortfolio

Section titled “3.7b GET /api/v1/wallets/{address}/portfolio · owner|agent · SDK getPortfolio”

Balances + byChain + byVenue + asOf + freshness. Wallet-keyed.

3.7c GET /api/v1/wallets/{address}/performance · owner|agent · SDK getPerformance

Section titled “3.7c GET /api/v1/wallets/{address}/performance · owner|agent · SDK getPerformance”

Realized yield since inception, net 30d, current APY per venue (null if unavailable — never fabricated), blended APY.

3.7d POST /api/v1/wallets/batch/positions · owner|agent · SDK batchPositions

Section titled “3.7d POST /api/v1/wallets/batch/positions · owner|agent · SDK batchPositions”
{ "wallets": ["0xabc…", "So1…"] }

Max 50. Each result is { walletAddress, ok, position|error }.

3.7e GET /api/v1/day/venues/apy · public · SDK venueApyTable

Section titled “3.7e GET /api/v1/day/venues/apy · public · SDK venueApyTable”

Every DAY venue with grossApyBps or status: "unavailable". Fail-closed on live read failure.

3.7f GET /api/v1/day/errors · public · SDK errorCatalog

Section titled “3.7f GET /api/v1/day/errors · public · SDK errorCatalog”

Versioned error + blocker enum (enumVersion). Envelope: { code, message, retryable, blockers[] }. Renaming a code is breaking.

3.8 POST /api/v1/wallets/{address}/preview · owner|agent · SDK previewRoute

Section titled “3.8 POST /api/v1/wallets/{address}/preview · owner|agent · SDK previewRoute”
{ "amountMicros": "1000000", "stake": false, "token": "USDC" }

Never mutates. planStatus: "prepared".

3.9 POST /api/v1/wallets/{address}/route · owner · SDK routeYield

Section titled “3.9 POST /api/v1/wallets/{address}/route · owner · SDK routeYield”

Credits liquid (and optional stake if Auto Yield on). Idempotency-Key supported.

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

Agent key → 403. Principal fee 0.

3.10 POST /api/v1/wallets/{address}/harvest · permissionless · SDK harvest

Section titled “3.10 POST /api/v1/wallets/{address}/harvest · permissionless · SDK harvest”
{ "compound": true, "execute": true }
SituationResponse
No staked balanceHTTP 422, mode: "no_op_harvest", outcome: "blocked", gross "0"
Live claim unavailablegross "0", reason yield_unavailable / etc.
Real claim microsskim 500 bps → protocolFeeMicros / netYieldMicros / compound

Never accept client-invented gross without fixture flags (disabled in prod).

3.11 POST /api/v1/wallets/{address}/withdraw · owner · SDK withdraw

Section titled “3.11 POST /api/v1/wallets/{address}/withdraw · owner · SDK withdraw”
{ "amountMicros": "500000", "token": "USDC", "unstakeFirst": true }

Principal fee 0. Agent → 403.

3.12 POST /api/v1/wallets/{address}/auto-pay · owner · SDK enableAutoPay

Section titled “3.12 POST /api/v1/wallets/{address}/auto-pay · owner · SDK enableAutoPay”
{ "enabled": true, "percentage": 30, "targets": ["storage", "inference"] }

3.13 POST /api/v1/day/bridge/plan · public · SDK bridgePlan

Section titled “3.13 POST /api/v1/day/bridge/plan · public · SDK bridgePlan”
{
"sourceChain": "sui",
"destChain": "solana",
"amountMicros": "1000000",
"sourceAddress": "0xOWNER",
"destinationAddress": "So1…1112"
}

Aliases: fromChain/toChain, amount, from/to.
Blocked responses always include blockers[], blockerDetails, requiredFields, supportedLanes.

DAY-251 lifecycle: prepareowner_signsubmitdelivery_trackingcredit_after_delivery.
ownerMustSign: true, custody.teamIntermediateWallet: false, credit only after confirmed delivery.

DAY-254 disclosures: every plan includes fees (protocol bridge fee 0, venue pass-through) and risks (codes + summary + timeout).

3.14 POST /api/v1/day/bridge/rescue · owner · SDK bridgeRescuePlan

Section titled “3.14 POST /api/v1/day/bridge/rescue · owner · SDK bridgeRescuePlan”

Failed / timeout / under-minOut delivery → funds destination always owner (DAY-253).
Cannot redirect: destinationAddressownerAddressblocked + destination_not_owner.
Response includes statusSurface (timeout, refundEligible, destinationLockedToOwner).

3.14b POST /api/v1/day/bridge/delivery · owner|keeper

Section titled “3.14b POST /api/v1/day/bridge/delivery · owner|keeper”

Credit gate: actual ≥ minOut + destination proof. Timeout/refund → rescue, never credit.
statusSurface on every response. Idempotent on bridgeTxId.

3.14c POST /api/v1/wallets/{address}/autopilot/decide · owner|agent

Section titled “3.14c POST /api/v1/wallets/{address}/autopilot/decide · owner|agent”

DAY-255: within-chain only. decide() never emits cross-chain REBALANCE or bridge legs.
Bridge is an explicit owner/agent Mayan plan (/bridge/plan), not an autopilot action.

3.15 POST /api/v1/day/gas-sponsor/plan · public

Section titled “3.15 POST /api/v1/day/gas-sponsor/plan · public”

Prepare-only gas sizing.

On-chain package ids (day-packages.v1). Base and Arbitrum include live vs target blocks: DayRegistry live ≠ execution home.

FieldMeaning
phase1Homes["sui","solana"]Executable route homes
expansionHomes["base","arbitrum"]Map / discovery (registry may be live)
labelsPer-chain Map | Executable
chains.*.statusContract/program deploy status — not adapter write-readiness
honestyMap-vs-Executable rules; fee 500 bps yield / 0 principal

Arbitrum/Base enablement: stub adapters → broadcastEnabled is always false even when the global broadcast flag is on.

3.16b Base cage (DAY-231) · prepare-only until Base GO

Section titled “3.16b Base cage (DAY-231) · prepare-only until Base GO”

Offchain OwnerPolicy + capability parity on Base (DayRegistry-bound). Wallet-only identity. Day never holds keys; ownerMustSign: true, submitted: false.

MethodPathAuth
GET/api/v1/day/base/cagepublic — action vocabulary + invariants
GET/api/v1/wallets/{address}/base/cageowner|agent
GET/PUT/api/v1/wallets/{address}/base/policyowner|agent / owner — venue + payee allowlists, caps
GET/api/v1/wallets/{address}/base/capabilityowner|agent
POST/api/v1/wallets/{address}/base/capability/grantowner
POST/api/v1/wallets/{address}/base/capability/revokeowner (immediate total)
POST/api/v1/wallets/{address}/base/actionowner — prepare ROUTE|EXIT|REBALANCE|HARVEST|COMPOUND|AUTOPAY

Destination-lock: venues and payees must be owner-allowlisted; EXIT destination is the owner only; free-form transfer addresses are rejected. Capability scopes: route, exit, rebalance, harvest, compound, autopay.

Arbitrum honesty (DAY-237): chains.arbitrum.status=live means DayRegistry is deployed (0x00f09EEdfF406217D5CF7adf60E8873760F67e38, chainId 42161). It does not mean live deposits — writeReady / liveMoneyPath stay false while adapters are stubs. Superseded registry (no fee caps): 0x342d57cf3d9cf7d35267b834327b37A1f9638752.

3.16c GET /api/v1/day/arbitrum · public · SDK arbitrumProfile

Section titled “3.16c GET /api/v1/day/arbitrum · public · SDK arbitrumProfile”

Arbitrum expansion profile. goNoGo is NO_GO_EXPANSION or PREPARE_OK_STUBS — never imply live write.

3.16d GET /api/v1/day/arbitrum/enablement · public · SDK arbitrumEnablement

Section titled “3.16d GET /api/v1/day/arbitrum/enablement · public · SDK arbitrumEnablement”

DAY-243 write gate: broadcastEnabled stays false until chain writeReady + OPEN_YIELD_ARBITRUM_WRITE_GO. Per-adapter writeReady: false for stubs. UI must not treat PREPARE_OK_STUBS as live deposits.

3.16e GET /api/v1/day/arbitrum/wallet-balance?address= · public · SDK arbitrumWalletBalance

Section titled “3.16e GET /api/v1/day/arbitrum/wallet-balance?address= · public · SDK arbitrumWalletBalance”

DAY-242 read-only ETH + USDC for a wallet address (identity = wallet only, DAY-294). On RPC fail each leg is N/A — never invent balances. No keys / no broadcast.

3.17 GET /api/v1/day/discover · public · SDK listOpportunities

Section titled “3.17 GET /api/v1/day/discover · public · SDK listOpportunities”

Public DefiLlama map / discovery (also POST /api/v1/day/discover with filters). Not execution truth — adapters own APY.

3.18 GET /api/v1/day/base · public · SDK baseProfile()

Section titled “3.18 GET /api/v1/day/base · public · SDK baseProfile()”

Base expansion profile (role: expansion_discovery). DayRegistry may be live; execution is off until write adapters + OPEN_YIELD_BASE_EXECUTION.

3.19 GET /api/v1/day/base/enablement · public · SDK baseEnablement()

Section titled “3.19 GET /api/v1/day/base/enablement · public · SDK baseEnablement()”

Enablement gate (DAY-230): goNoGo=NO_GO_EXPANSION, executionEnabled=false today. Response includes live vs target. Do not claim Base as an execution home until write adapters are ready.

3.20 GET /api/v1/day/base/wallet-balance?address= · public · SDK baseWalletBalance(address)

Section titled “3.20 GET /api/v1/day/base/wallet-balance?address= · public · SDK baseWalletBalance(address)”

Read-only ETH + Circle USDC on Base (DAY-235). Fail-closed: RPC failure → null balances / 502, never fabricates amounts.

Terminal window
curl -sS "$BASE/day/base/wallet-balance?address=0x0000000000000000000000000000000000000001" | jq '{status,eth,usdc,blockers}'

Also: GET /api/v1/day/sui/wallet-balance?address= · GET /api/v1/day/solana/wallet-balance?address=.

Full OpenAPI 3.1 for codegen.


Terminal window
BASE=https://dayprotocol.com/api/v1
KEY=$DAY_OWNER_API_KEY
WALLET=walkthrough-1
# Discover
curl -sS "$BASE/day/strategies" | jq '.strategies[] | select(.strategyId=="suilend")'
# Preview credit (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 .
# 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 '{success,depositedAmountMicros,feeOnDepositMicros,staked}'
# Position
curl -sS -H "X-API-Key: $KEY" "$BASE/wallets/$WALLET/position" | jq '{liquidMicros,stakedMicros}'
# Venue deposit plan (owner signs offchain)
curl -sS -X POST -H 'content-type: application/json' \
-d '{"strategyId":"suilend","amountMicros":"1000000"}' \
"$BASE/day/strategies/deposit/plan" | jq '{status,ownerMustSign,submitted,feeMicros}'
# 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}'
# Withdraw principal
curl -sS -X POST -H "X-API-Key: $KEY" -H 'content-type: application/json' \
-d '{"amountMicros":"1000000"}' \
"$BASE/wallets/$WALLET/withdraw" | jq .

Fee check: route/withdraw → fee micros 0. Harvest with real yield → 5% of gross.


Terminal window
# Prepared
curl -sS -X POST https://dayprotocol.com/api/v1/day/bridge/plan \
-H 'content-type: application/json' \
-d '{
"sourceChain":"sui",
"destChain":"solana",
"amountMicros":"1000000",
"sourceAddress":"0xOWNER_SUI",
"destinationAddress":"So11111111111111111111111111111111111111112"
}' | jq '{status,rail,blockers,supportedLanes}'
# Missing field → blocked with requiredFields
curl -sS -X POST https://dayprotocol.com/api/v1/day/bridge/plan \
-H 'content-type: application/json' \
-d '{"sourceChain":"sui","destChain":"solana"}' | jq '{status,blockers,requiredFields,blockerDetails}'
# Rescue (owner key) — destination locked to owner
curl -sS -X POST https://dayprotocol.com/api/v1/day/bridge/rescue \
-H "X-API-Key: $DAY_KEY" -H 'content-type: application/json' \
-d '{"ownerAddress":"0xOWNER","asset":"USDC","amountMicros":"1000000"}' | jq .
await day.bridgePlan({
sourceChain: "sui",
destChain: "solana",
amountMicros: "1000000",
sourceAddress: "0x…",
destinationAddress: "So1…",
});
await day.bridgeRescuePlan({ ownerAddress: "0x…", asset: "USDC", amountMicros: "1000000" });

5b. In-chain swap plans (Jupiter / Turbos / EVM)

Section titled “5b. In-chain swap plans (Jupiter / Turbos / EVM)”

Prepare-only owner-sign paths. Never custody. ownerMustSign: true, submitted: false.

EndpointChainVenue
POST /api/v1/day/jupiter/planSolanaJupiter
POST /api/v1/day/turbos/planSuiTurbos
POST /api/v1/day/evm/swap/planBase / ArbitrumUniswap-v3 class

Fees (disclosed as feeLineItems):

LineDefault
Protocol swap fee100 bps (protocolSwapFeeBps, from bps.mjs)
Pool / venue feeestimate (poolFeeBps, default 30; stables 5 on EVM)

Slippage: default slippageBps=100, hard max 500 (blocked above max).
Idempotency: body idempotencyKey or header — shape oy_&lt;op>_&lt;walletAddress>_&lt;nonce> (e.g. oy_jupiter_So1…_1).

Terminal window
# Solana Jupiter (DAY-245)
curl -sS -X POST "$BASE/day/jupiter/plan" \
-H 'content-type: application/json' \
-d '{
"mintIn":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"mintOut":"So11111111111111111111111111111111111111112",
"amountIn":"1000000",
"ownerAddress":"So1…",
"slippageBps":100,
"idempotencyKey":"oy_jupiter_So1_1"
}' | jq '{status,ownerMustSign,protocolSwapFeeBps,feeLineItems,slippageBps,submitted}'
# Sui Turbos (DAY-246)
curl -sS -X POST "$BASE/day/turbos/plan" \
-H 'content-type: application/json' \
-d '{"coinIn":"USDC","coinOut":"SUI","amountIn":"1000000","ownerAddress":"0x…"}' \
| jq '{status,feeLineItems,ownerMustSign}'
# Base / Arb EVM (DAY-247) — USDC↔native or stable↔stable; prepare-only until chain GO
curl -sS -X POST "$BASE/day/evm/swap/plan" \
-H 'content-type: application/json' \
-d '{"chain":"base","tokenIn":"USDC","tokenOut":"native","amountIn":"1000000","ownerAddress":"0x…"}' \
| jq '{status,pairKind,executionMode,feeLineItems,ownerMustSign,submitted}'

Response always includes feeLineItems (protocol + pool estimate), amountInAfterProtocolFee, and never sets submitted: true from this API.


{ "code": "UNAUTHORIZED", "message": "owner required" }
codeHTTPMeaning
UNAUTHORIZED403Missing/wrong role
INVALID_API_KEY401Unknown key
WALLET_SCOPE403Character not in key scope
NOT_FOUND404Unknown route / strategy / form
RATE_LIMITED429Rate limit
INTERNAL_ERROR500Server fault (no internal leak)

Many plan endpoints return HTTP 200 with status: "blocked" and blockers: ["…"] (not 4xx) — check status / blockers in the body.


ActionFee
deposit / route / withdraw principal0
strategy deposit/withdraw planfeeMicros: "0"
harvest yield500 bps of gross → protocolFeeMicros
swap plan (Jupiter/Turbos/EVM)100 bps protocol + pool fee line items
gas sponsor plan100 bps (plan field)

Example: gross yield 20000 micros → protocol 1000, net 19000.


MethodHTTP
listVenues / listStrategiesGET venues / strategies
getStrategyGET strategies/{id}
prepareStrategyDeposit / prepareStrategyWithdrawPOST …/plan
getPositionGET …/position
previewRoute / routeYieldPOST preview / route
harvest / withdraw / enableAutoPayPOST harvest / withdraw / auto-pay
bridgePlan / bridgeRescuePlanPOST bridge/plan · rescue
readiness / sdkRelease / apiVersionmeta

Constructor: { baseUrl, apiKey, sessionToken?, fetchImpl?, checkUpdate? }.
Client sends X-DAY-API-Client-Version. Server returns X-DAY-API-Version*.


VerDateNotes
v1 / 1.0.02026-07-11First formal DAY API v1 — OpenAPI 3.1, /api/v1/* prefix, X-API-Key auth, owner|agent reads, executionMode, live claim opt-in, bridge contract, bare strategyId

Related: DAY-264–269 (XEL rail), DAY-140/143 (auth), DAY-280 (docs/OpenAPI), XEL-182.


GET /api/v1/day/routes returns the full machine manifest.
GET /openapi.json is the OpenAPI 3.1 expansion with request schemas for integrator endpoints.