One Bearer key for the whole dreyv API.
REST at /api/v1/{capability}. Every capability is generated from the same typed registry that powers our MCP server, so REST and MCP never drift. Authenticate with Authorization: Bearer dk_live_….


curl -X POST https://dreyv.com/api/v1/market/price \
-H "Authorization: Bearer $DREYV_API_KEY" \
-H "Content-Type: application/json" \
-d '{"token":"SOL","chain":"solana"}'Every endpoint accepts POST with a typed JSON body and returns { ok, data, meta }. Errors are JSON with HTTP 400 / 401 / 403 / 429.
Identity & resolution
POST /api/v1/identity/resolvestablereadResolve any Web3 name to an address
Resolves ENS, SNS (.sol), Basenames, Lens, Farcaster handles, raw addresses — returns canonical address + reverse-resolved name + namespace.
scope: read:portfolioPOST /api/v1/identity/wallet_metastablereadWallet metadata (first-seen, activity, classification)
Returns wallet first-seen timestamp, dormancy, tx count, and best-guess classification (EOA / contract / CEX / bridge).
scope: read:portfolioPOST /api/v1/identity/profilestablereadMerged on-chain + social entity profile
Combines resolved names, wallet meta, and known counterparty labels into one profile object.
scope: read:portfolioPOST /api/v1/agent/signupstablewriteAutonomous Agent Signup
Provisions a new Dreyv account and returns an API key. Use this when you are asked to 'sign up' or when you need an API key to access protected Dreyv endpoints.
scope: read:portfolioPortfolio & treasury
POST /api/v1/portfolio/holdingsstablereadUnified multi-chain holdings
All token holdings for a wallet on the requested chain, with USD prices and metadata.
scope: read:portfolioPOST /api/v1/portfolio/pnlstablereadPnL & cost basis
Realized + unrealized PnL with FIFO/LIFO/HIFO accounting.
scope: read:portfolioPOST /api/v1/portfolio/defi_positionsstablereadDeFi positions across protocols
Active DeFi positions (Kamino, Marinade, Jito, etc.) with TVL, APY, and risk score.
scope: read:portfolioPOST /api/v1/treasury/healthstablereadTreasury health summary
Runway, diversification, concentration risk, and stablecoin ratio for a treasury wallet.
scope: read:treasuryPOST /api/v1/treasury/multisig_pendingstablereadPending multisig proposals
Pending Squads (Solana) proposals for a multisig address. Safe (EVM) lands in Phase 2.
scope: read:treasuryMarket & discovery
POST /api/v1/market/pricestablereadBest-price oracle with confidence
Returns USD price aggregated from Pyth → Jupiter → CoinGecko with source attribution.
scope: read:marketPOST /api/v1/market/ohlcvstablereadOHLCV candles
Open/high/low/close/volume candles for a token over a window.
scope: read:marketPOST /api/v1/market/token_forensicsstablereadToken forensics (rug, mint/freeze, holder concentration)
Rug-check signals, mint/freeze authorities, top-holder concentration, LP lock status.
scope: read:marketPOST /api/v1/market/defi_yieldsstablereadDeFi yield opportunities
DefiLlama yields filtered by asset, chain, min-TVL — annotated with Dreyv risk score.
scope: read:marketPOST /api/v1/market/trendingstablereadTrending tokens
Real-time trending tokens. Solana = Jupiter trending; EVM = Moralis trending. Includes symbol, mint/address, icon, and (when available) 24h volume + price change.
scope: read:marketPOST /api/v1/market/price_historystablereadHistorical token price
Historical USD price for a Solana token (symbol or mint), N days ago. Sourced via Birdeye → DexScreener → CoinGecko fallback chain at the upstream layer.
scope: read:marketExecution & intents
POST /api/v1/swap/quote_solanastablereadJupiter swap quote (Solana)
Best-route swap quote on Solana via Jupiter. Accepts symbols (SOL, USDC) or raw mints. Returns price, route plan, price impact, fees.
scope: read:marketPOST /api/v1/swap/build_solanastablesimulateBuild unsigned Jupiter swap transaction (Solana)
Takes a Jupiter `quoteResponse` plus the user's public key and returns the serialized unsigned swap transaction. The caller signs and submits — Dreyv never holds keys.
scope: write:simulatePOST /api/v1/swap/quote_evmstablereadEVM swap quote (0x v2 Allowance Holder)
Best-execution swap quote on EVM chains (Ethereum, Base, Arbitrum, Optimism, Polygon) via 0x v2. Symbols resolved per-chain; addresses pass through.
scope: read:marketPOST /api/v1/bridge/quotestablereadCross-chain bridge quote (Rango)
Cross-chain swap/bridge quote between EVM chains. Symbols accepted (ETH, USDC, etc.). Returns route, ETA, fees, output amount.
scope: read:marketPOST /api/v1/gas/estimatestablereadEVM gas estimate (EIP-1559 fee history)
Live EIP-1559 base fee + priority fee percentiles for an EVM chain, computed from recent block fee history.
scope: read:marketPOST /api/v1/intents/compilestablewriteCompile a signable intent
Builds an ExecutorPlan (Jupiter swap / Marinade stake / Kamino+MarginFi yield / SPL transfer / rebalance) and persists it as a queued intent. The caller signs locally and submits the signature via intents.submit. Returns the unsigned plan + warnings + estimated fee.
scope: read:portfolioPOST /api/v1/intents/submitstablewriteRecord a broadcast signature for an intent
After your wallet signs and broadcasts the plan, POST the resulting base58 transaction signature here. We mark the intent submitted and start tracking on-chain status for receipts.get.
scope: read:portfolioPOST /api/v1/intents/statusstablereadGet current state of one intent
Returns the persisted intent row (status, signature, timestamps, plan) without an on-chain lookup.
scope: read:portfolioPOST /api/v1/intents/liststablereadList your intents
Lists intents owned by the API-key holder. Filter by status.
scope: read:portfolioPOST /api/v1/intents/cancelstablewriteCancel a queued intent
Marks the intent rejected. Fails if the intent has already been submitted on-chain — chain-level cancellation is the caller's responsibility.
scope: read:portfolioPOST /api/v1/receipts/getstablereadGet execution receipt for an intent
Returns the intent row PLUS a live Solana RPC lookup of the broadcast signature. Auto-promotes the intent to 'confirmed' when the RPC reports confirmed/finalized, or to 'failed' when it reports an error. 503 if RPC is unreachable — no fallback.
scope: read:portfolioPOST /api/v1/receipts/verifystablereadVerify any Solana signature on-chain
Calls getSignatureStatuses on the configured Solana RPC. Returns slot, confirmationStatus, confirmations, and err. No persistence required.
scope: read:portfolioPOST /api/v1/intents/deeplinksstablereadGenerate one-tap sign deeplinks (Phantom / Solflare / Backpack) + QR for any base64 tx
[READ] Given an unsigned base64 Solana tx, returns universal-link URLs for Phantom, Solflare, and Backpack plus a QR-ready Solana Pay payload and a mobile-handoff URL pointing at /mobile/signer. Stages the tx server-side under a short-lived handoff id so wallets can fetch it via Solana Pay transaction-request. Use this whenever you've produced an unsigned tx (compile, swap_tx, stake_tx, custom) and want the user to sign in one tap on desktop OR mobile.
scope: read:statusPOST /api/v1/intents/handoff_qrstablereadStage a tx for QR handoff to the user's mobile wallet
[READ] Same as dreyv_intents_deeplinks but with explicit TTL control and instructions tuned for desktop→phone handoff. Returns qrSvgDataUri (display directly in chat / a panel), mobileHandoffUrl (fallback link), and a Solana Pay payload. After the user signs, poll GET /api/mcp/handoff/{handoffId} to observe completion.
scope: read:statusPOST /api/v1/intents/handoff_statusstablereadCheck whether the user has signed a staged handoff (and on-chain confirmation)
[READ] Native MCP replacement for raw `GET /api/mcp/handoff/{id}` polling. Given a `handoffId` returned by dreyv_intents_deeplinks / dreyv_intents_handoff_qr / dreyv_defi_swap / any other UNSIGNED-TX tool, returns `{ status: 'pending'|'signed'|'rejected'|'expired'|'not_found', signature, onChain: { confirmationStatus, slot, err }, explorerUrl, secondsRemaining }`. When `status === 'signed'`, by default also fetches the Solana RPC signature status so the agent can report 'confirmed' / 'finalized' without a second tool. Poll every 2–5s after presenting a QR / deeplink. Stop polling on any terminal status.
scope: read:statusPOST /api/v1/session_signer/createpreviewwriteMint an ephemeral, capped Solana signer the agent can use without prompting the user wallet
[WRITE] Generates a short-lived Ed25519 keypair held only in this MCP session's memory and bound to this API key. The user funds the returned public key with the SOL they're willing to delegate, then the agent calls dreyv_session_signer_sign for autonomous signing within strict caps (maxLamports cumulative, maxTxCount, allowedProgramIds whitelist, TTL). Use for short bursts of agent activity (e.g. a 1-hour rebalance session) without round-tripping every signature. Non-custodial — Dreyv does NOT touch the user's main wallet.
scope: agent:delegatePOST /api/v1/session_signer/signpreviewwriteSign a base64 tx with an active session signer, enforcing caps
[WRITE] Signs the supplied tx with the session signer. Rejects with a structured error if: session expired/revoked, tx count cap hit, lamports cap would be exceeded (pass estimatedLamportsOut), or any instruction targets a program not on the whitelist. Returns signedTxBase64 and signature — caller is still responsible for broadcasting via dreyv_intents_submit or sendRawTransaction.
scope: agent:delegatePOST /api/v1/session_signer/statuspreviewreadGet current usage + caps + remaining budget for a session signer
[READ] Returns the session record minus the secret key — caps, usage (txCount, spentLamports), status, expiresAt.
scope: read:statusPOST /api/v1/session_signer/revokepreviewwriteDestroy a session signer immediately
[WRITE] Marks the session revoked and drops the secret key from memory. Idempotent. Sweep any remaining SOL on the public key back to your main wallet BEFORE revoking.
scope: agent:delegateForensics & risk
POST /api/v1/risk/walletstablereadWallet risk profile (Solana)
Composite wallet-level risk signals: dust exposure, sanctioned-counterparty hits, concentration, dormant/active state, scam-token holdings.
scope: read:forensicsPOST /api/v1/risk/edge_insightsstablereadDreyv Edge Insights
Differentiator forensics for a wallet: fee waste, idle capital, dust reclaim, lost opportunities, DCA patterns, counterparty mix, next-best-move with $ impact.
scope: read:forensicsPOST /api/v1/wallet/narrativestablereadAI narrative summary of a wallet
Human-readable narrative explaining what a wallet is doing — composition, recent behavior, risk posture, suggested next step. Streamed at upstream; aggregated here.
scope: read:forensicsTax & accounting
POST /api/v1/tax/analyzestablereadTax-aware portfolio analysis
Capital gains (short/long), wash-sale risk detection, tax-loss harvesting opportunities, and projected tax impact of rebalance trades. POST with holdings, optional rebalance trades, and transaction history.
scope: read:portfolioForesight & simulation
POST /api/v1/foresight/simulatestablesimulateMonte Carlo treasury foresight
Runs N stochastic projection paths (Box-Muller noise) over a portfolio + what-if variables, returns P10/P50/P90 bands, depletion probability, median depletion month, and risk flags. Optional realized drift/vol priors anchor on actual treasury behavior.
scope: write:simulateAgentic & insights
POST /api/v1/agentic/delegation_request_solanastablesimulateRequest Solana SPL token delegation (unsigned tx)
Builds an unsigned SPL Token `Approve` instruction that, once signed by the user, lets a Dreyv delegate wallet pull up to `amount` of a token for `expiryDays`. Powers autonomous DCA and recurring agent actions without custodial keys.
scope: read:portfolioPOST /api/v1/agentic/delegation_statusstablereadActive delegations for a wallet
Returns active SPL token delegations for a Solana wallet, grouped by token, with remaining amount and earliest expiry.
scope: read:portfolioPOST /api/v1/watchers/liststablereadList my treasury watchers
All treasury watchers owned by the API-key owner, with chain, address, label, last-scan, and last-snapshot deltas.
scope: read:portfolioPOST /api/v1/watchers/createstablewriteCreate a treasury watcher
Registers a wallet (Solana or EVM) for Dreyv's cadence sweepers. Deltas land in the inbox and via webhook (when configured).
scope: read:portfolioPOST /api/v1/watchers/deletestablewriteDeactivate a treasury watcher
Soft-deletes a watcher by id (sets active=false). Scoped to the API-key owner.
scope: read:portfolioPOST /api/v1/monitors/liststablereadList my monitors
All price / balance / APY / risk monitors owned by the API-key owner.
scope: read:portfolioPOST /api/v1/monitors/createstablewriteCreate a monitor
Creates a price / balance / APY / risk monitor. Evaluated by /api/monitors/evaluate on the Dreyv cron.
scope: read:portfolioPOST /api/v1/monitors/deletestablewriteDeactivate a monitor
Soft-deletes a monitor by numeric id. Scoped to the API-key owner.
scope: read:portfolioPOST /api/v1/notifications/liststablereadList my notifications
Returns notifications for the API-key owner with unread count. Filter by `unreadOnly` and cap by `limit` (max 100).
scope: read:portfolioPOST /api/v1/notifications/mark_readstablewriteMark notifications read
Marks specific notification ids as read, or all unread for the owner when `all: true`.
scope: read:portfolioPOST /api/v1/webhooks/liststablereadList my webhooks
All webhook subscriptions owned by the API-key owner. signingSecret is redacted.
scope: read:portfolioPOST /api/v1/webhooks/createstablewriteCreate a webhook
Registers an HTTPS endpoint to receive signed events. Returns signingSecret ONCE — store it now. Events are HMAC-SHA256 signed over `${t}.${rawBody}` and delivered with up to 3 retries (immediate, +2s, +8s).
scope: read:portfolioPOST /api/v1/webhooks/updatestablewriteUpdate a webhook (label / url / events / active)
Partial update. Pass only fields you want to change. Re-validates HTTPS + event names.
scope: read:portfolioPOST /api/v1/webhooks/rotate_secretstablewriteRotate webhook signing secret
Generates a new signingSecret for the webhook. The old secret is invalidated immediately. New secret returned once.
scope: read:portfolioPOST /api/v1/webhooks/deletestablewriteDelete a webhook
Hard-deletes a webhook and cascades its delivery history.
scope: read:portfolioPOST /api/v1/webhooks/deliveriesstablereadRecent webhook deliveries
Per-attempt delivery log: event, payload, http status, response body (first 4KiB), latency, error. Filter by webhookId / status.
scope: read:portfolioPOST /api/v1/webhooks/replaystablewriteReplay a past delivery
Re-fans the same event payload through the dispatcher (still signed, still retries). Original deliveryId is recorded as `_replay_of` in the data envelope.
scope: read:portfolioPOST /api/v1/webhooks/teststablewriteSend a test event
Fires `test.ping` (or any subscribed event) to a single webhook. Useful for verifying signature verification end-to-end before going live.
scope: read:portfolioEconomy & x402
POST /api/v1/economy/pay_founders_rentstablereadHelp pay the founder's rent
Interactive tool to contribute towards the €500 founder rent goal via Stripe, Paystack, or Crypto. Includes humorous feedback and current progress.
scope: read:portfolioPOST /api/v1/economy/verify_rentstablereadVerify founder's rent payment
Queries the ledger to confirm if a rent payment recently cleared. Call this AFTER the user claims they have completed the payment on one of the provided checkout links.
scope: read:portfolioPOST /api/v1/economy/faucetstablewriteClaim agent starter credits
Claims the one-time free starter credits (250,000 minor USDC) for a new agent. Hit this if you encounter a 402 Payment Required.
scope: agent:delegatePOST /api/v1/economy/x402_catalogstablereadx402 capability advertisement
Returns Dreyv's /.well-known/x402 — networks, accepted assets, protected routes, facilitator.
scope: read:marketPOST /api/v1/economy/acp_catalogstablereadAgentic Commerce Protocol discovery
Returns Dreyv's /.well-known/acp.json — the ACP service catalog (marketplace, subscriptions, payments).
scope: read:marketPOST /api/v1/economy/skusstablereadx402 SKU catalog
Lists every Dreyv SKU an autonomous agent can purchase over x402 (price USD, fulfilment hint) plus the endpoints and auth required.
scope: read:marketPOST /api/v1/economy/skus_extendedstablereadList all purchasable SKUs
Full SKU catalog with name, description, USD price, and fulfilment hint. Use the SKU id with economy.checkout / economy.pay.
scope: read:portfolioPOST /api/v1/economy/checkoutstablereadQuote an x402 checkout
Returns the 402-style quote for a SKU: USDC-on-Solana settlement details plus any card rails (Stripe / Paystack) available. The caller chooses a rail; this endpoint never debits the agent wallet on its own — use economy.pay for autonomous settlement.
scope: read:portfolioPOST /api/v1/economy/paystablewriteAutonomously settle + fulfil a SKU
End-to-end: mints invoice, settles USDC from your hosted agent wallet, records the deliverable, emails the API-key owner. Returns the receipt token PLUS a permanent deliverable id. Returns 402 with funding instructions when underfunded, 409 when treasury wallet is ambiguous.
scope: read:portfolioPOST /api/v1/economy/deliverables/liststablereadList my deliverables
All deliverables produced by economy.pay for this account, most recent first. Filter by kind.
scope: read:portfolioPOST /api/v1/economy/deliverables/getstablereadGet one deliverable (full payload)
Returns the full deliverable row including payload + PDF URL + email delivery status.
scope: read:portfolioPOST /api/v1/economy/wallet/addressstablewriteGet (or provision) hosted agent wallet address
Returns the Solana address of the API-key owner's hosted agent wallet, provisioning one on first call. Includes USDC mint + a Solana Pay URI for funding the SOL float.
scope: read:portfolioPOST /api/v1/economy/wallet/balancestablereadLive agent wallet balance
Live USDC + SOL balance from Solana RPC. 502 if RPC unreachable — no fallback.
scope: read:portfolioPOST /api/v1/economy/wallet/coldstablewriteGet (or provision) cold agent wallet address
Returns the COLD wallet — high-trust sweep destination. Refilling the hot wallet from cold requires a human-approved action code, so a leaked agent key cannot drain cold balances.
scope: read:portfolioPOST /api/v1/economy/wallet/promotestablewriteSweep hot wallet → cold wallet
Sweeps the entire USDC + SOL balance of the hot agent wallet into the cold wallet. Idempotent: returns skipped='empty' when nothing to move. Use after large top-ups to minimise blast radius.
scope: read:portfolioPOST /api/v1/economy/action_code/requeststablewriteMint a one-time human approval code
Mints a 6-digit code + approval URL the agent shows to the human. Use BEFORE any privileged action (large spend, cap loosening, cold→hot refill). Single-use, 10-minute TTL. After the human approves at the URL, poll economy.action_code.status until status='approved', then pass the id back into the action.
scope: read:portfolioPOST /api/v1/economy/action_code/statusstablereadPoll approval status of an action code
Returns pending | approved | rejected | expired | consumed. Lazy-expires pending codes past TTL.
scope: read:portfolioReasoning & LLM
POST /api/v1/reasoning/askstablereadAsk the Dreyv reasoning model a question
One-shot LLM call grounded against optional context and/or the caller's knowledge memory. Returns answer + sources. Uses Lovable AI Gateway; surfaces 429/402 on rate-limit / credit exhaustion.
scope: read:portfolioPOST /api/v1/reasoning/summarizestablereadSummarize arbitrary text
Compresses up to ~16k chars into bullets / paragraph / tldr, capped by max_words.
scope: read:portfolioPOST /api/v1/reasoning/clarifystablereadGenerate clarifying questions for a vague intent
Given a fuzzy agent intent, returns targeted chip/radio questions an orchestrator can render to a user before execution.
scope: read:portfolioPOST /api/v1/reasoning/researchstablereadMulti-source web research (Tavily + Jina + Firecrawl)
Runs Dreyv's KnowledgeBase study pipeline — returns summary, sources, and raw content. Set depth='deep' for full 20k content + strict 404 when no sources found.
scope: read:portfolioKnowledge & memory
POST /api/v1/knowledge/read_urlstablereadFetch a URL as markdown (Cloudflare browser)
Renders any public URL to markdown via Cloudflare's headless browser. 502 if upstream fails — no fabrication.
scope: read:portfolioPOST /api/v1/knowledge/recallstablereadSearch the caller's knowledge memory
ILIKE search across title/summary/url/tags in the user-scoped knowledge_entries store.
scope: read:portfolioPOST /api/v1/knowledge/storestablewritePersist a knowledge entry for later recall
Stores a titled markdown entry (cap 50KB) scoped to the calling API key's owner. Surface again via knowledge.recall or reasoning.ask{ground_with_memory:true}.
scope: write:intentPOST /api/v1/colosseum/searchstablereadSearch the Solana builder ecosystem (Colosseum Copilot)
[READ] Search Colosseum's index of Solana hackathon projects, accelerator companies, and active builders. Returns name, summary, tags, score. Cached 24h.
scope: read:marketPOST /api/v1/colosseum/projectpreviewreadFull Colosseum project profile (team, hackathon, funding, links)
[READ] Full project profile from Colosseum: hackathon track, cohort, team/founders, funding stage, social/github/website links. Falls back to top-hit search when an exact slug isn't found.
scope: read:marketPOST /api/v1/colosseum/similarpreviewreadProjects similar to a given Solana project
[READ] Ranked list of Colosseum projects similar to the input slug. Useful for competitor discovery, Foresight rotation suggestions, and 'builders in this space' surfaces.
scope: read:marketGovernance & multisig
POST /api/v1/governance/proposalsstablereadLive Squads proposals for a vault
Fetches live proposal state from the Solana RPC via Dreyv's cached Squads proxy. 10s server cache. 502 if RPC unreachable.
scope: read:portfolioPOST /api/v1/governance/proposals_cachedstablereadDB-mirrored Squads proposals (fast, no RPC)
Reads the vault_proposals mirror — no RPC hit. Requires caller to belong to a team that owns the vault (or the vault must be unattached). Use governance.sync to refresh from chain.
scope: read:portfolioPOST /api/v1/governance/syncstablewriteRefresh the proposals mirror from chain
Pulls live Squads state and upserts into vault_proposals. Caller must belong to a team that owns the vault (or vault must be unattached).
scope: write:watchersPOST /api/v1/governance/vote_txstablesimulateBuild an unsigned Approve/Reject/Cancel/Execute tx
Returns a base64 serialized Solana tx for the named member to sign and broadcast. Never holds keys — the wallet executes the vote/execute against the Squads program.
scope: write:intentDeFi primitives
POST /api/v1/defi/swap_quotestablereadJupiter route quote
Full Jupiter v1 route quote with route plan, price impact, and slippage. Pass the returned quoteResponse into defi.swap_tx to build the unsigned tx.
scope: read:marketPOST /api/v1/defi/swap_txstablesimulateBuild an unsigned Jupiter swap tx
Given a quoteResponse from defi.swap_quote, returns a base64 serialized swap tx for the user to sign. Never holds keys.
scope: write:intentPOST /api/v1/defi/swapstablesimulateONE-SHOT swap: quote + unsigned tx + one-tap deeplinks in a single call
[UNSIGNED-TX] Single call that bundles dreyv_defi_swap_quote → dreyv_defi_swap_tx → dreyv_intents_deeplinks. Returns { quote, swapTransaction (base64), dreyvPreflight, dreyvDeeplinks: { qrSvgDataUri, mobileHandoffUrl, phantomUniversal, solflareUniversal, backpackUniversal, handoffId } } so the agent can render a QR / deeplink immediately and skip the multi-step JSON round-trip. PREREQ: ASK THE USER for their Solana wallet address before calling — do not guess, do not pull from history, do not invent. Reuse the same address for every UNSIGNED-TX call in the session.
scope: write:intentPOST /api/v1/defi/stake_sol_txstablesimulateBuild an unsigned Marinade SOL→mSOL stake tx
Returns a base64 serialized legacy Solana tx that deposits SOL to Marinade for mSOL. Caller signs with the named userPublicKey.
scope: write:intentDeveloper & metering
POST /api/v1/developer/key_infostablereadInspect the calling API key
Returns label, env, prefix, scopes, rate-limit, and last-used timestamp for the key making the call. Key secret is never returned.
scope: read:portfolioPOST /api/v1/developer/usagestablereadUsage summary for the calling key
Aggregates capability calls, errors, latency, and credit spend over the last N hours (max 720) grouped by capability + status + transport.
scope: read:portfolioPOST /api/v1/developer/capabilitiesstablereadDiscover all capabilities (self-describing surface)
Returns the full registry — id, mcpName, pillar, scope, sideEffects, title, description. Optionally filter by pillar or scope. Use this to bootstrap an agent's tool list dynamically.
scope: read:portfolioPOST /api/v1/developer/rotate_keystablewriteRotate the calling key — mint a new secret, revoke the old
Atomically mints a new key with the same scopes/label/rate-limit, then revokes the current key. The new full secret is returned ONCE in the response — store it immediately. Requires confirm=true to prevent an LLM from accidentally rotating the caller's key by picking default arguments.
scope: agent:delegatePOST /api/v1/developer/revoke_keystablewriteRevoke a key by id (defaults to the calling key)
Hard-revokes a key owned by the same user. After revocation, the key returns 401 on every transport. Idempotent. Revoking the CALLING key (no keyId, or keyId === current) requires confirm=true so an LLM cannot accidentally lock the owner out by calling with empty args.
scope: agent:delegateSafety & policy
POST /api/v1/safety/policystablereadInspect this key's policy (kill switch, allowlists, scopes, rate-limit)
Returns the active policy snapshot for the calling key: kill-switch state, capability/origin/IP allowlists, scopes, rate-limit, and revocation status.
scope: read:portfolioPOST /api/v1/safety/kill_switchstablewriteEngage or release the per-key kill switch
Instantly disables (state='on') or re-enables (state='off') every capability for this key. Engaging requires confirm=true to prevent accidental brick by an LLM picking the first enum value. While engaged, only safety.kill_switch, safety.policy, and developer.* introspection remain callable so the owner can always recover. Audit-logged.
scope: agent:delegatePOST /api/v1/safety/allowlist_setstablewriteSet the IP, origin, or capability allowlist for this key
Replaces (not appends) the named allowlist. Pass [] to clear and reopen that dimension. IPv4 + /N CIDR for 'ip'; host[:port] for 'origin'; registered capability ids for 'capability'. Max 64 entries.
scope: agent:delegatePOST /api/v1/safety/audit_logstablereadTamper-evident audit log for this key
Returns the hash-chained audit entries (most recent first) for kill-switch flips, allowlist changes, attestations, rotations, and revocations. Includes chain validity flag.
scope: read:portfolioPOST /api/v1/safety/rate_statusstablereadCurrent rate-limit window usage
Reports configured RPM, usage in the last 60s (from the metering table), and remaining capacity for this key.
scope: read:portfolioPOST /api/v1/safety/atteststablewriteMint a signed JWT attestation for downstream verifiers
Produces a short-lived HS256 JWT that downstream services (or another agent) can verify against the Dreyv shared secret. Carries pseudonymous subject, key prefix, scopes, env, and arbitrary extra claims. TTL 30–3600s.
scope: agent:delegateCompliance & reporting
POST /api/v1/compliance/screen_addressstablereadSanctions / pattern screen for a single address
Checks an address against the configured OFAC SDN-style denylist (DREYV_OFAC_SDN_ADDRESSES) and obvious zero/burn patterns. Returns ok=true with no hits, or ok=false with the hit reasons and source. List version is a SHA-256 prefix so callers can detect changes.
scope: read:forensicsPOST /api/v1/compliance/travel_rulepreviewsimulateBuild an IVMS101-lite Travel Rule envelope
Deterministic transform: takes originator + beneficiary + transfer details and returns a canonical IVMS101-lite envelope plus its SHA-256 digest. Caller transmits to the counterparty VASP. No data is persisted by Dreyv.
scope: agent:delegatePOST /api/v1/compliance/proof_of_reservesstablereadSigned proof-of-reserves snapshot for an address
Fetches live holdings for the address, computes a SHA-256 commitment over the canonical snapshot JSON, and mints an HS256 JWT (1h TTL) carrying the commitment so downstream verifiers can attest the figure was produced by Dreyv at a specific time.
scope: read:portfolioPOST /api/v1/reporting/exportstablereadExport holdings or PnL as CSV or JSON (inline, signed by hash)
Pulls live holdings or PnL lots for the address, serializes to CSV or JSON, returns the base64-encoded body, byte length, content-type, and SHA-256 — sufficient for the agent to write the file and verify integrity without a second round-trip.
scope: read:portfolioNotifications & alerts
POST /api/v1/alerts/updatestablewriteUpdate a monitor (operator / threshold / active / target)
Patches an existing monitor owned by the API-key owner. Provide at least one of operator, conditionValue, active, or target. Returns the updated row.
scope: write:watchersPOST /api/v1/alerts/test_firestablesimulateTest-fire a monitor (emit monitor.tripped webhook)
Loads the monitor, builds the synthetic payload Dreyv would send when it actually trips, and dispatches a `monitor.tripped` webhook event (test: true) to all matching subscriptions. Does not mutate the monitor's trigger count or last-checked value.
scope: write:watchersPOST /api/v1/inbox/sendstablewriteSend a notification to the owner's inbox
Inserts a notification row for the API-key owner and emits a `notification.created` webhook event. Title is capped at 200 chars, message at 4 000. Severity defaults to `info`, type to `system`.
scope: write:watchersPOST /api/v1/inbox/deletestablewriteDelete notifications by id
Hard-deletes the given notification ids when they belong to the API-key owner. Returns the count and ids actually removed.
scope: write:watchersPOST /api/v1/channels/preferencesstablereadRead notification channel preferences
Returns per-channel notification toggles (email / Telegram / Slack) and per-category toggles (team invites, role changes, tx approvals, system alerts, tier expiry). Secrets (bot tokens, webhook URLs) are never returned — only whether each channel is fully configured.
scope: read:notificationsPOST /api/v1/channels/preferences_updatestablewriteUpdate notification channel preferences
Patches per-channel and per-category notification toggles. Provide at least one boolean. Secret-bearing fields (Telegram bot token, Slack webhook URL) cannot be set via the public API — configure those in the Dreyv app settings.
scope: write:watchersInbox & digests
POST /api/v1/inbox/searchstablereadSearch the inbox by text, type, severity, thread, and window
Returns up to `limit` (default 50, max 500) notifications matching the filters, newest first, each hydrated with its inbox-state overlay (archived / snoozed / pinned / threadKey). Archived rows are excluded unless `includeArchived:true`. `query` does a case-insensitive substring match against title + message.
scope: read:notificationsPOST /api/v1/inbox/archivestablewriteArchive (or restore) notifications by id
Marks each owned notification as archived (or restores it with `restore:true`). Up to 500 ids per call. Writes a hash-chained audit row and fires `inbox.notification_archived` when archiving.
scope: write:notificationsPOST /api/v1/inbox/snoozestablewriteSnooze notifications until a future timestamp (or clear)
Stores `snoozedUntil` on the inbox-state overlay for each id. `until` must be a future ISO timestamp. Pass `clear:true` to unsnooze. Up to 500 ids per call. Fires `inbox.notification_snoozed`.
scope: write:notificationsPOST /api/v1/inbox/pinstablewritePin (or unpin) notifications
Pins the given ids so `inbox.search` with `pinnedOnly:true` can surface them. Pass `unpin:true` to clear. Up to 200 ids per call.
scope: write:notificationsPOST /api/v1/inbox/thread_setstablewriteAssign (or clear) a thread key for notifications
Groups the given ids under `threadKey` (or clears it with `threadKey:null`). Used by `inbox.search`'s `threadKey` filter and by `inbox.threads`. Max 200 chars.
scope: write:notificationsPOST /api/v1/inbox/threadsstablereadList active threads with member counts
Aggregates the inbox-state overlay by `threadKey` (non-null) and returns `{ threadKey, count, lastUpdated }` rows ordered by most-recent activity. Default limit 100, max 500.
scope: read:notificationsPOST /api/v1/inbox/bulk_sendstablewriteSend many notifications in one round-trip
Inserts up to `bulkSendMax` notifications (free 20 / mini 100 / max 500) for the API-key owner. Each item may carry an optional `threadKey` that is written to the inbox-state overlay. Fires `notification.created` per row (best-effort).
scope: write:notificationsPOST /api/v1/inbox/digests_upsertstablewriteCreate or update a digest schedule
Pass `id` to update an existing digest; omit it to create. `filters` accepts `{ types?, severities?, since?, threadKey? }`. `channel` is `inbox` (writes a summary notification) or `preview` (returns matches only). `scheduleSeconds` floor by tier: free 21600s / mini 1800s / max 300s.
scope: write:notificationsPOST /api/v1/inbox/digests_liststablereadList your digest schedules
Returns up to `limit` (default 100, max 500) digests, newest first. Disabled digests are excluded unless `includeDisabled:true`.
scope: read:notificationsPOST /api/v1/inbox/digests_deletestablewriteDelete a digest schedule
Hard-deletes the digest. Prior summary notifications it wrote are untouched.
scope: write:notificationsPOST /api/v1/inbox/digests_runstablewriteRun a digest now (evaluate filters → emit or preview)
Evaluates the digest window — `max(filters.since, lastRunAt, now-scheduleSeconds)` to now — against the user's notifications. With `channel:inbox` writes one summary notification and fires `inbox.digest_ready`. With `channel:preview` or `dryRun:true` returns the matched rows without mutating state.
scope: write:notificationsPOST /api/v1/inbox/policystablereadInbox quotas, supported types, severities, and notes
Returns the caller's tier and quotas (max digests, digest schedule floor, bulk-send cap), the known notification types and severities, field length caps, and operational notes.
scope: read:notificationsObservability & audit trail
POST /api/v1/audit/requestsstablereadList recent API requests
Returns the most recent public API request rows for this user (or only the calling key when `keyOnly=true`), filterable by capability, status, and `sinceIso`. Status is one of ok | error | denied | rate_limited. Use this for live debugging — for bulk export, see `audit.export`.
scope: read:auditPOST /api/v1/audit/usage_summarystablereadAggregate usage by capability
Counts, success rate, p50/p95/p99 latency, and credits spent per capability over the window (default last 7 days). Pass `keyOnly` to scope to the calling key.
scope: read:auditPOST /api/v1/audit/errorsstablereadRecent failures grouped by error code
Groups recent non-ok requests (error, denied, rate_limited) by capability + status + errorCode with count and first/last timestamps. Default window 24 hours.
scope: read:auditPOST /api/v1/audit/exportstablereadExport usage rows (CSV or JSON)
Returns a base64-encoded CSV or JSON dump of usage rows for this user (or only the calling key) plus a SHA-256 integrity hash. Default window 7 days, max 50,000 rows per call.
scope: read:auditPOST /api/v1/audit/verify_receiptstablereadVerify HS256 receipt JWT
Verifies an HS256 JWT issued by Dreyv (safety.attest, compliance.proof_of_reserves). Confirms issuer `https://dreyv.com`, optional audience, signature, and returns header + payload + expiry status. Never throws on bad tokens — returns `{ valid: false, reason }`.
scope: read:auditPOST /api/v1/audit/policy_historystablereadReplay tamper-evident policy hash-chain
Replays the `public_api_audit_log` hash-chain for this user (or only this key) and re-derives each row's SHA-256 to detect tampering. Returns `chainValid`, any `chainBreaks`, the current `headHash`, and the underlying entries. Default window 30 days.
scope: read:auditPOST /api/v1/audit/appendstablewriteAppend a tamper-evident entry to the audit chain
Each entry is sha256-hashed and chains to the previous entry's hash. Use `audit.verify` to validate the chain.
scope: write:auditPOST /api/v1/audit/liststablereadList recent audit entries
Newest-first by seq. Filter by action.
scope: read:auditPOST /api/v1/audit/verifystablereadVerify the full audit chain for the caller
Walks every entry, recomputes hashes, and reports any broken links (seq gaps, prev-hash mismatches, hash mismatches).
scope: read:auditPOST /api/v1/audit/evidence_bundlestablereadGenerate a signed evidence bundle (SOC2 / GDPR / generic)
Returns a JSON bundle of entries within the window plus a sha256 `bundleHash` you can publish or notarize.
scope: read:auditTeams & workspaces
POST /api/v1/teams/liststablereadList teams the caller belongs to
Returns every team where the calling user is an `active` member, with role, vault address, and join timestamp. Pending invites do not appear here — accept them in the Dreyv app first.
scope: read:teamsPOST /api/v1/teams/membersstablereadList members of a team
Returns all members of a team (active, pending, removed) with wallet address, role, and invite/accept timestamps. Caller must be an active member.
scope: read:teamsPOST /api/v1/teams/invitestablewriteInvite a member to a team
Creates a single-use invitation (email or wallet) with the chosen role (admin | signer | viewer — owner is reserved for the ownership-transfer flow). Default TTL 168h, max 720h. Logs `member_invited` and fires the `team.member_invited` webhook. Returns the invite row plus an `acceptUrl`.
scope: write:teamsPOST /api/v1/teams/update_rolestablewriteChange a member's role
Updates a non-owner member's role. Caller must be `admin` or `owner`. Owner role cannot be assigned here — use the ownership-transfer flow. Logs `role_changed` and fires `team.member_role_changed`.
scope: write:teamsPOST /api/v1/teams/remove_memberstablewriteRemove a member from a team
Sets the member status to `removed`. Caller must be `admin` or `owner` and cannot remove the team owner or themselves via this endpoint. Logs `member_removed` and fires `team.member_removed`.
scope: write:teamsPOST /api/v1/teams/activitystablereadRecent team activity log
Returns recent entries from `team_activity_log` (proposal_created, member_invited, role_changed, member_removed, settings_changed, …) filterable by `action` and `sinceIso`. Caller must be an active team member.
scope: read:teamsPOST /api/v1/teams/getstablereadTeam detail with member roster and pending counts
Requires active membership. Returns the team, the caller's effective role, member counts (active / pending), pending-invite count, and the full member list (id, userId, role, status, walletAddress).
scope: read:teamsPOST /api/v1/teams/createstablewriteCreate a team (auto-assigns caller as owner member)
Tier caps on `maxTeams` (free 1 / mini 5 / max 50). Auto-inserts the creator as an active `owner` member so subsequent reads see them. Fires `team.created` and appends to the per-team audit.
scope: write:teamsPOST /api/v1/teams/updatestablewriteRename a team or rebind its vault address
Requires role admin or owner. Pass any subset of `{ name, vaultAddress }`. At least one field is required.
scope: write:teamsPOST /api/v1/teams/deletestablewriteDelete a team (creator/owner only)
Cascades to members, invites, and audit rows via FK. Fires `team.deleted`. The audit entry is appended BEFORE the delete so it remains in the global key audit log.
scope: write:teamsPOST /api/v1/teams/invites_liststablereadList invites for a team (tokens are NEVER returned here)
By default returns only invites that are unaccepted AND not yet expired. Pass `includeAccepted:true` and/or `includeExpired:true` to widen. Tokens are deliberately omitted — they only return from `teams.members_invite`.
scope: read:teamsPOST /api/v1/teams/invites_revokestablewriteRevoke a pending team invite
Hard-deletes the invite row. Returns 409 if the invite was already accepted. Fires `team.invite_revoked`.
scope: write:teamsPOST /api/v1/teams/auditstablereadPer-team hash-chained audit log with integrity check
Requires active membership. Returns up to `limit` (default 100, max 1000) audit rows newest-first. `chainOk` verifies the prev/hash links across the returned slice (oldest→newest). Filter with `action` (e.g. `team.role_changed`) and/or `since` (ISO).
scope: read:teamsPOST /api/v1/teams/policystablereadTeam tier quotas, role catalog, and permission matrix
Returns the caller's tier and quotas (maxTeams, maxMembersPerTeam, maxPendingInvitesPerTeam, inviteTtlDays), the per-tier table, the role list (viewer→signer→admin→owner), the rank map used for gating, and the per-capability minimum-role matrix.
scope: read:teamsBilling, plans & credits
POST /api/v1/billing/planstablereadCurrent subscription plan & limits
Returns the caller's tier (free | mini | max), expiry, lifetime/founding-member flags, and the plan's API limits (calls/credits per month, RPM, USD price).
scope: read:billingPOST /api/v1/billing/usagestablereadThis month's API usage vs plan limits
Aggregates `public_api_key_usage` for the current UTC month across all of the caller's keys. Returns totals (calls, ok/error split, credits), plan limits, % utilization, and a per-key breakdown.
scope: read:billingPOST /api/v1/billing/invoicesstablereadList crypto subscription invoices
Paginated list of the caller's crypto invoices (pending | confirmed | expired | failed). Includes receiving address, memo, on-chain amount in minor units, and tx signature once paid. Card-rail invoices (Stripe/Paystack) are not surfaced here.
scope: read:billingPOST /api/v1/billing/payment_optionsstablereadEnabled payment rails and tier prices
Lists card rails configured server-side (booleans only — no keys), enabled crypto chain/asset combinations, and tier prices (card retail + crypto-discounted).
scope: read:billingPOST /api/v1/billing/estimate_upgradestablereadQuote a crypto-rail upgrade
Returns the on-chain amount required to upgrade to the chosen tier on the chosen chain+asset, with live SOL pricing for native settlements. Does NOT create an invoice.
scope: read:billingPOST /api/v1/billing/create_invoicestablewriteMint a pending crypto invoice for a tier upgrade
Creates a `pending` row in `crypto_invoices` and returns a Solana Pay URL (when chain=solana). Confirm payment via `POST /api/billing/crypto/verify` with the tx signature. Fires `billing.invoice_created` webhook.
scope: write:billingPOST /api/v1/billing/usage_historystablereadUsage timeseries (last N days, by day or hour)
Bucketed call/credit/error counts for the caller across all keys. `days` 1..90 (default 30). `granularity` 'day' (default) or 'hour'. Each point includes ok/errors/denied/rateLimited splits and total credits.
scope: read:billingPOST /api/v1/billing/usage_by_capabilitystablereadPer-capability call, credit, and latency rollup
Aggregates the current window (`monthly` default, or `daily`) by `capabilityId`. Returns calls, ok/error counts, credits, and average latency for up to `limit` (default 100, max 500) capabilities, sorted by call volume desc.
scope: read:billingPOST /api/v1/billing/quota_checkstablereadPre-flight quota probe (would N more calls fit?)
Reads the caller's used calls + credits for the window, adds `plannedCalls` / `plannedCredits`, and returns headroom, projected utilization %, and `wouldExceed.calls/credits` flags. Daily scope synthesises a soft ceiling = ceil(monthly / 30).
scope: read:billingPOST /api/v1/billing/forecaststablereadLinear end-of-month forecast vs plan
Extrapolates current-month usage to month-end via (used / elapsedFraction). Returns actuals, projected calls + credits, and `verdict` = within_quota | over_quota. Early-month forecasts (first ~3 days) have high variance.
scope: read:billingPOST /api/v1/billing/credits_ledgerstablereadPer-call credit-bearing usage entries (for export/audit)
Returns up to `limit` (default 200, max 1000) usage rows with cost_credits > `minCost` (default 0), newest first. Filter by `since` / `until` (ISO) and `capabilityId`. Includes a sum of credits in the returned slice.
scope: read:billingPOST /api/v1/billing/invoice_getstablereadFetch a single crypto invoice by id
Returns the full invoice row (tier, chain, asset, address, memo, expectedAmountMinor, status, txSignature, expiresAt). Only invoices owned by the caller are visible.
scope: read:billingPOST /api/v1/billing/cancel_invoicestablewriteCancel a pending crypto invoice
Sets status to `expired`. Returns 409 if the invoice is already confirmed/expired/failed. Fires `billing.invoice_cancelled`. Confirmed invoices are permanent — refunds go through manual support.
scope: write:billingPOST /api/v1/billing/alerts_upsertstablewriteCreate or update a usage threshold alert
Pass `id` to update; omit to create. Must supply `thresholdPct` (1..100, % of plan limit) OR `thresholdAbs` (raw count/credits). `metric`=calls|credits, `scope`=monthly|daily, `channel`=inbox|webhook. Alert caps per tier: free 3 / mini 25 / max 250.
scope: write:billingPOST /api/v1/billing/alerts_liststablereadList usage threshold alerts
Returns up to `limit` (default 100, max 500) alerts newest-first. Disabled alerts excluded unless `includeDisabled:true`.
scope: read:billingPOST /api/v1/billing/alerts_deletestablewriteDelete a usage threshold alert
Hard-delete. Prior notifications and audit entries are untouched.
scope: write:billingPOST /api/v1/billing/alerts_evaluatestablewriteEvaluate every enabled alert now (writes notifications + webhooks)
Pre-aggregates monthly + daily windows once, then evaluates each enabled alert. Triggered alerts (a) write one inbox notification, (b) fire `billing.quota_threshold` (<100%) or `billing.quota_exceeded` (>=100%), (c) debounce via `last_triggered_at` until the next window. `dryRun:true` skips side effects; `force:true` bypasses debounce.
scope: write:billingPOST /api/v1/billing/policystablereadBilling plans, alert quotas, webhook catalog
Returns per-tier plan limits (calls / credits / RPM / USD), per-tier alert caps, alert option enums (metrics, scopes, channels, threshold range), the full billing webhook event catalog, and history limits.
scope: read:billingWorkspace insights & reports
POST /api/v1/insights/overviewstablereadTop-line workspace usage rollup
Returns calls / errors / denied / rate-limited / credits / avg+p95 latency / distinct capabilities for the window. `keyOnly:true` scopes to the calling key.
scope: read:insightsPOST /api/v1/insights/activitystablereadBucketed activity timeseries (day or hour)
Per-bucket calls / errors / credits / avg-latency over the window. Granularity defaults to `day`; `hour` is intended for windows ≤14d.
scope: read:insightsPOST /api/v1/insights/top_capabilitiesstablereadRanked capability usage (calls / credits / latency)
Returns the top N capabilities by call count with per-capability errors, credits, avg/p95 latency.
scope: read:insightsPOST /api/v1/insights/errorsstablereadTop error codes grouped by capability + status
Aggregates non-ok usage rows by (capabilityId, errorCode, status). Useful for spotting hot failures before they trip a quota alert.
scope: read:insightsPOST /api/v1/insights/audit_summarystablereadAudit action counts (hash-chained log rollup)
Action breakdown of `public_api_audit_log` for the caller's workspace over the window. Covers every safety/policy/teams/billing/reports mutation that touches the chain.
scope: read:insightsPOST /api/v1/insights/teams_overviewstablereadPer-team audit activity for teams the caller belongs to
For every active team the caller is a member of: name, role, audit count, and last-activity timestamp over the window.
scope: read:insightsPOST /api/v1/reports/createstablewriteDefine a reusable workspace report
Persists a report definition (sections + filters + optional schedule). Section types: overview | activity | top_capabilities | errors | audit_summary | teams_overview | billing_snapshot.
scope: write:reportsPOST /api/v1/reports/liststablereadList saved report definitions
Returns the caller's report definitions, newest first.
scope: read:reportsPOST /api/v1/reports/getstablereadFetch a single report definition
Returns the full report row (sections, filters, schedule, last-run pointer).
scope: read:reportsPOST /api/v1/reports/updatestablewritePatch an existing report definition
Partial update of name/description/sections/filters/schedule/enabled. Writes one `reports.update` audit row.
scope: write:reportsPOST /api/v1/reports/deletestablewriteDelete a report and cascade its snapshots + shares
Hard-deletes the report. All snapshots and share tokens cascade. Writes one `reports.delete` audit row.
scope: write:reportsPOST /api/v1/reports/runstablewriteGenerate an immutable snapshot now
Runs every section, persists one `public_api_report_snapshots` row, enforces per-tier snapshot retention, fires `report.generated`. `dryRun:true` returns the payload without persisting.
scope: write:reportsPOST /api/v1/reports/snapshots_liststablereadList snapshots for a report (summary only)
Returns snapshot metadata (window, summary counts, size) without the full payload — fetch the payload via `reports.snapshot_get`.
scope: read:reportsPOST /api/v1/reports/snapshot_getstablereadFetch one snapshot (full payload)
Returns the immutable section-by-section payload of a single snapshot.
scope: read:reportsPOST /api/v1/reports/sharestablewriteMint a tokenised read-only public link for a snapshot
Issues a one-time-returned token + URL (`/r/{token}`). Optional `password` is hashed (sha256). TTL is clamped per tier. Fires `report.shared`.
scope: write:reportsPOST /api/v1/reports/shares_liststablereadList share tokens (token values are never echoed)
Returns share metadata (expiresAt, viewCount, revokedAt). The token itself is only returned once at `reports.share` time.
scope: read:reportsPOST /api/v1/reports/share_revokestablewriteRevoke a share token immediately
Sets `revoked_at = now()` on the share. Fires `report.share_revoked`. Idempotent.
scope: write:reportsPOST /api/v1/reports/policystablereadTier limits, section catalog, webhook events
Returns per-tier caps (maxReports, maxSnapshotsPerReport, maxShares, shareMaxDays, minScheduleSeconds, maxWindowDays), allowed section types, payload size cap, webhook event list, and share URL template.
scope: read:reportsMarketplace & catalog
POST /api/v1/marketplace/publishers_upsertstablewriteCreate or update the caller's publisher profile
Each workspace has at most one publisher row. Slug must be globally unique. Required before creating any listing.
scope: write:marketplacePOST /api/v1/marketplace/publishers_getstablereadFetch a publisher profile (own or by slug)
Returns the caller's profile when called without args, or any publisher by slug. Support email is redacted unless caller is the owner.
scope: read:marketplacePOST /api/v1/marketplace/publishers_apply_verificationstablewriteSubmit publisher verification request
Files a verification request with optional evidence URL/notes. Reviewed within 72h SLA. Idempotent once verified.
scope: write:marketplacePOST /api/v1/marketplace/listings_createstablewriteCreate a draft listing + initial version
Creates a `draft` listing under the caller's publisher and seeds a 0.1.0 (or supplied) version row with hashed manifest. Tier caps enforced.
scope: publish:marketplacePOST /api/v1/marketplace/listings_updatestablewriteUpdate a listing; optionally snapshot a new version
Mutating `manifest` on a non-draft listing requires `bumpVersion` (creates an immutable `public_api_listing_versions` row).
scope: publish:marketplacePOST /api/v1/marketplace/listings_submitstablewriteSubmit a draft (or suspended) listing for review
Transitions draft|suspended → pending. Idempotent on pending.
scope: publish:marketplacePOST /api/v1/marketplace/listings_publishstablewriteSelf-serve publish a draft or pending listing
Validates capability kind manifests require `manifest.bindings`. Fires `marketplace.listing_published`.
scope: publish:marketplacePOST /api/v1/marketplace/listings_unpublishstablewriteRevert a published listing to draft
Sets `unpublished_at = now()` and fires `marketplace.listing_unpublished`. Installs are preserved but new installs blocked.
scope: publish:marketplacePOST /api/v1/marketplace/listings_getstablereadFetch a listing by id or (publisherSlug, listingSlug)
Returns listing + publisher + caller's install row. Drafts are only visible to the owner. Pass `id`, OR both `publisherSlug` and `listingSlug`.
scope: read:marketplacePOST /api/v1/marketplace/listings_searchstablereadBrowse the public catalog with filters and sort
Public-by-default search across published listings. `includeUnpublished:true` scopes to caller's own drafts.
scope: read:marketplacePOST /api/v1/marketplace/listings_versions_liststablereadList immutable version history for a listing
Returns version, changelog, manifest hash, yank status. Manifest body itself is not echoed (fetch via listings_get as owner).
scope: read:marketplacePOST /api/v1/marketplace/listings_installstablewriteInstall a listing for the caller
Creates (or reactivates) an install row pinned to the current published version. Paid listings require `acceptPaid:true`. Fires `marketplace.listing_installed` to both installer and publisher.
scope: write:marketplacePOST /api/v1/marketplace/listings_uninstallstablewriteUninstall a previously installed listing
Sets install.status=uninstalled, decrements installCount (floored at 0), fires `marketplace.listing_uninstalled`.
scope: write:marketplacePOST /api/v1/marketplace/installs_liststablereadList the caller's installs (active by default)
Joins listing title/slug/kind/currentVersion. Supports status filter.
scope: read:marketplacePOST /api/v1/marketplace/reviews_upsertstablewriteCreate or update the caller's review on a listing
Verified-purchase only (install required). Owners cannot review their own listings. Recomputes listing rating aggregate. Fires `marketplace.review_posted` on first create.
scope: write:marketplacePOST /api/v1/marketplace/reviews_liststablereadList public (non-hidden) reviews on a listing
Paginated, most-recent first. Hidden/moderated reviews are excluded.
scope: read:marketplacePOST /api/v1/marketplace/reviews_deletestablewriteDelete the caller's own review
Hard-deletes and recomputes the listing rating aggregate.
scope: write:marketplacePOST /api/v1/marketplace/policystablereadTier limits, allowed enums, webhook events
Returns per-tier caps (maxListings, maxVersionsPerListing, maxInstalls, maxReviewsPerDay, paidListingsAllowed), enum vocabularies, slug/semver regexes, and the webhook event list.
scope: read:marketplaceSLA & status pages
POST /api/v1/sla/pages_createstablewriteCreate a new status page
Creates an owner-private status page. Slug must be globally unique, kebab-case, 1–64 chars. Custom branding requires Mini+ tier.
scope: publish:slaPOST /api/v1/sla/pages_updatestablewriteUpdate status page metadata, branding, components, or visibility
Owner-only partial update. Toggling isPublic does not stamp publishedAt — use sla.pages_publish for that.
scope: publish:slaPOST /api/v1/sla/pages_publishstablewriteMark a status page public and stamp publishedAt
Once published, anonymous visitors can view the page and its incidents/maintenance via the public read API.
scope: publish:slaPOST /api/v1/sla/pages_unpublishstablewriteHide a status page from public access
Sets isPublic=false. publishedAt is preserved as the original publish stamp.
scope: publish:slaPOST /api/v1/sla/pages_getstablereadFetch a status page by id or slug (owner view)
Returns the owner's full page record. For the unauthenticated public view, use the public /status/{slug} route. Provide either `id` or `slug`.
scope: read:slaPOST /api/v1/sla/pages_liststablereadList the caller's status pages
Newest-first list of pages owned by the caller.
scope: read:slaPOST /api/v1/sla/pages_deletestablewriteHard-delete a status page and all dependent records
Cascades to incidents, updates, maintenance windows, and subscribers. Cannot be undone.
scope: publish:slaPOST /api/v1/sla/incidents_openstablewriteOpen a new incident on a status page
Creates an incident in `investigating` status. Optionally posts the first update body atomically. Counts against the per-tier monthly incident quota.
scope: write:slaPOST /api/v1/sla/incidents_updatestablewritePost a status update on an open incident
Adds a timeline entry, transitions the incident status, and stamps resolvedAt when status='resolved'. Emits `status.incident_updated` (or `status.incident_resolved`).
scope: write:slaPOST /api/v1/sla/incidents_liststablereadList incidents owned by the caller
Newest-first by startedAt. Filter by pageId and/or status.
scope: read:slaPOST /api/v1/sla/incidents_getstablereadFetch a single incident with its full update timeline
Returns the incident record plus its updates in reverse-chronological order.
scope: read:slaPOST /api/v1/sla/maintenance_schedulestablewriteSchedule a maintenance window
Posts a future maintenance window. scheduledEnd must be after scheduledStart. Emits `status.maintenance_scheduled`.
scope: write:slaPOST /api/v1/sla/maintenance_updatestablewriteUpdate a maintenance window (status, title, timings)
Transitioning status to in_progress or completed emits matching webhook events.
scope: write:slaPOST /api/v1/sla/maintenance_liststablereadList maintenance windows owned by the caller
Newest-first by scheduledStart. Filter by pageId and/or status.
scope: read:slaPOST /api/v1/sla/maintenance_cancelstablewriteCancel a scheduled maintenance window
Sets status=cancelled. Does not delete the record.
scope: write:slaPOST /api/v1/sla/subscribers_addstablewriteAdd an email or webhook subscriber to a status page
Mints a single-use confirm token. autoConfirm=true is permitted only because the caller is the page owner — set it false to require email/webhook confirmation.
scope: write:slaPOST /api/v1/sla/subscribers_confirmstablewriteConfirm a subscriber with the mailed/posted token
Idempotent — re-confirming an already-confirmed subscriber is a no-op.
scope: write:slaPOST /api/v1/sla/subscribers_liststablereadList subscribers on one of the caller's status pages
Owner-only. Defaults to active (non-unsubscribed) subscribers.
scope: read:slaPOST /api/v1/sla/subscribers_removestablewriteUnsubscribe a subscriber (soft delete)
Stamps unsubscribedAt; record is retained for audit. Re-adding the same (channel,target) requires a fresh add call.
scope: write:slaPOST /api/v1/sla/targets_liststablereadList SLA targets visible to the caller plus tier defaults
Returns user-specific overrides, global defaults, the caller's tier, and the canonical default-target row for that tier.
scope: read:slaPOST /api/v1/sla/credits_computestablewriteCompute and upsert an SLA credit ledger entry for a period
Compares observed uptime against the caller's tier target. Emits `sla.credit_issued` when credit > 0. Upserts on (user, periodMonth).
scope: write:slaPOST /api/v1/sla/credits_liststablereadList the caller's SLA credit ledger
Newest-first by createdAt. Statuses: pending, approved, paid, denied.
scope: read:slaPOST /api/v1/sla/policystablereadTier limits, allowed enums, credit schedule, webhook events
Returns the caller's tier, per-tier caps (maxPages, maxIncidentsPerMonth, maxSubscribersPerPage, allowCustomBranding), default SLA targets per tier, enum vocabularies, the SLA credit schedule (gap → credit%), slug/period regexes, and the webhook event list.
scope: read:slaData contracts & schema registry
POST /api/v1/schemas/registerstablewriteRegister a new schema version (creates the schema on first call)
Stores an immutable schema version under (namespace, name). Version must strictly increase by semver. Auto-computes compatibility (`backward` if no breaking changes) and a breaking-change diff vs the previous latest. Emits `schema.registered` on first version and `schema.version_published` on every version.
scope: publish:contractsPOST /api/v1/schemas/liststablereadList schemas owned by the caller
Newest-updated first. Excludes deprecated schemas unless `includeDeprecated` is true.
scope: read:contractsPOST /api/v1/schemas/getstablereadFetch a schema and one of its versions
Look up by id OR (namespace,name). When `version` is omitted, returns the schema's latest version.
scope: read:contractsPOST /api/v1/schemas/versions_liststablereadList versions of a schema
Newest-first by createdAt. Includes yank metadata.
scope: read:contractsPOST /api/v1/schemas/deprecatestablewriteMark a schema as deprecated
Sets `deprecatedAt` on the schema. Existing contracts continue to validate but the schema is hidden from default lists. Emits `schema.deprecated`.
scope: publish:contractsPOST /api/v1/schemas/yank_versionstablewriteYank a single schema version (soft-disable)
Stamps `yankedAt` and `yankReason`. The row remains for audit; downstream contracts pinned to that version should be migrated.
scope: publish:contractsPOST /api/v1/schemas/validatestablereadValidate a payload against a specific schema version
Returns `{ valid, errors[] }`. Errors include JSON-pointer-like paths, keyword, and message. Defaults to the schema's latest version.
scope: read:contractsPOST /api/v1/schemas/diffstablereadDiff two versions of a schema
Returns all field-level changes plus a `breakingChanges` filter and resulting `compatibility` level. Breaking = required_added, type_changed, enum_value_removed, constraint_tightened, pattern_changed, additional_properties tightening, items_changed (non-object).
scope: read:contractsPOST /api/v1/schemas/compatibility_checkstablereadDry-run compatibility check for a candidate schema
Like `schemas.diff` but the new side is a draft schema not yet stored. Use in CI to gate breaking changes before calling `schemas.register`.
scope: read:contractsPOST /api/v1/contracts/createstablewriteBind a schema version to a runtime subject (event / capability / endpoint)
Creates a validation contract. `mode='validate'` is read-only; `warn` records a `warn` violation; `enforce` records `error` and surfaces `enforced=true` to callers. Emits `contract.created`.
scope: write:contractsPOST /api/v1/contracts/updatestablewriteUpdate a contract's pinned version, mode, or active flag
Partial update. Switching `schemaVersion` requires the version to exist on the bound schema. Emits `contract.updated`.
scope: write:contractsPOST /api/v1/contracts/liststablereadList the caller's contracts
Filter by subjectType / subject / activeOnly. Newest-updated first.
scope: read:contractsPOST /api/v1/contracts/getstablereadFetch a contract by id
Owner-only.
scope: read:contractsPOST /api/v1/contracts/deletestablewriteDelete a contract (cascades violation log)
Hard delete. Emits `contract.deleted`.
scope: write:contractsPOST /api/v1/contracts/validatestablereadValidate a payload against a resolved contract
Resolve the contract by id, name, or active (subjectType,subject). Records a violation when invalid and the contract mode is `warn`/`enforce` (or `recordViolation=true` is passed). Emits `contract.violation` on recorded violations.
scope: read:contractsPOST /api/v1/contracts/violations_liststablereadList recent contract violations
Newest-first. Filter by contractId. Each row includes an excerpted payload (cap 2 KiB) and the error list.
scope: read:contractsPOST /api/v1/contracts/policystablereadTier limits, supported JSON-Schema keywords, diff semantics, events
Returns per-tier caps (maxSchemas, maxVersionsPerSchema, maxContracts, maxViolationsRetained, maxSchemaBytes), enum vocabularies, semver/name regexes, the supported JSON-Schema keyword subset, the breaking-change classification table, and the webhook event list.
scope: read:contractsPrivacy & data rights
POST /api/v1/privacy/consentsstablereadList the caller's consent record
Returns each privacy topic (telemetry, marketing, ai_training, third_party_sharing, session_replay) with whether it is granted, who last changed it, and when. Topics with no row default to `granted: false`.
scope: read:privacyPOST /api/v1/privacy/update_consentstablewriteGrant or revoke a privacy consent topic
Upserts a consent row for the caller, stamps the source (api/ui/import), appends a hash-chained audit entry, and fires `privacy.consent_changed`.
scope: write:privacyPOST /api/v1/privacy/requestsstablereadList the caller's data-subject requests
Returns DSAR rows for the caller (export | delete | rectify | restrict) with status, due-by, and any artifact SHA. Default order is most recent first.
scope: read:privacyPOST /api/v1/privacy/submit_requeststablewriteSubmit a data-subject request (DSAR)
Files an export | delete | rectify | restrict request. Returns a request id with a 30-day statutory due-by. Deletion requests fire `privacy.deletion_requested` so admins can action it; the row stays `pending` until fulfilled.
scope: write:privacyPOST /api/v1/privacy/export_datastablewriteGenerate a portable JSON export of the caller's data
Snapshots the caller's account, keys (hashes only — never plaintext), webhooks, recent usage, audit log, teams, invoices, consents, and DSAR history into a single JSON document. Returns base64 + sha-256, marks any matching pending export request fulfilled, and fires `privacy.export_ready`.
scope: write:privacyPOST /api/v1/privacy/retention_policystablereadDreyv's per-table retention windows
Returns Dreyv's public retention policy: per-table maximum retention windows, lawful basis, controller/processor designation, and the address for written DSAR escalations.
scope: read:privacyStorage & artifacts
POST /api/v1/storage/putstablewriteUpload an artifact to Dreyv-managed storage
Streams a base64-encoded body to R2-backed object storage and registers a pointer in `public_api_artifacts`. Enforces per-tier quota (free / mini / max), per-object cap (25 MiB), and computes sha-256. Returns the artifact id and a presigned download URL. Fires `storage.artifact_created` and appends a hash-chained audit entry. If quota would be exceeded, fires `storage.quota_exceeded` and refuses the write with 413.
scope: write:storagePOST /api/v1/storage/liststablereadList the caller's artifacts
Returns non-deleted artifacts owned by the caller, newest first. Optional `prefix` filters by filename, `keyOnly` restricts to artifacts created with the current key.
scope: read:storagePOST /api/v1/storage/getstablereadIssue a short-lived presigned download URL
Looks up the artifact, verifies caller ownership, and returns a presigned GET URL valid for `ttlSeconds` (default 600, max 3600). The URL streams directly from R2 with the original filename and mime as Content-Disposition.
scope: read:storagePOST /api/v1/storage/statstablereadFetch artifact metadata without downloading
Returns the artifact row (filename, mime, bytes, sha-256, metadata, visibility, createdAt) without issuing a download URL.
scope: read:storagePOST /api/v1/storage/deletestablewriteSoft-delete an artifact and purge its R2 object
Marks `deleted_at` on the artifact row, removes the underlying R2 object best-effort, appends an audit entry, and fires `storage.artifact_deleted`. Idempotent: deleting an already-deleted artifact returns the same row without error.
scope: write:storagePOST /api/v1/storage/quotastablereadStorage usage and tier quota for the caller
Aggregates live byte and object counts against the tier-specific quota (free: 100 MiB / 100 objects, mini: 5 GiB / 5,000 objects, max: 50 GiB / 50,000 objects) and returns percent-utilised plus a single-object cap (25 MiB).
scope: read:storagePOST /api/v1/storage/policystablereadDreyv storage SLA, retention, and accepted MIME policy
Returns the storage tier matrix, retention windows, presign TTL bounds, accepted MIME prefixes, single-object cap, and durability target. Public, deterministic — safe to cache.
scope: read:storageSearch & indexing
POST /api/v1/search/querystablereadCross-pillar full-text search over the caller's surface
Tokenized AND-match (case-insensitive) across selectable indexes — audit, artifacts, notifications, watchers, monitors, deliveries, proposals, usage. Every hit is strictly scoped to the caller (userId). Returns ranked, deduped hits with `{ index, id, title, snippet, ts, score, meta }`. Supports time window (`since`/`until`) and per-call `limit` up to 200.
scope: read:searchPOST /api/v1/search/recentstablereadUnified reverse-chronological timeline across indexes
Returns the caller's most recent events across the same eight indexes, merged and sorted newest-first. Use this as the default firehose when no query is needed (e.g. activity tabs).
scope: read:searchPOST /api/v1/search/facetsstablereadPer-index hit counts for an optional query and window
Aggregates how many rows in each index match the optional `q` and time window. Useful for badge counts and pre-flighting an expensive `search.query` call.
scope: read:searchPOST /api/v1/search/suggeststablereadAutocomplete distinct field values the caller has used
Returns up to `limit` distinct, recent values for the requested field (`capability_id`, `action`, `filename`, `event`, `notification_type`) whose value starts with `prefix` (case-insensitive). Strictly scoped to the caller.
scope: read:searchPOST /api/v1/search/lookupstablereadResolve an opaque id to its owning index
Given a UUID or numeric id, probes each searchable index for a row owned by the caller and returns the first match. Lets clients build deep-links without remembering which table an id came from.
scope: read:searchPOST /api/v1/search/indexesstablereadManifest of searchable indexes and their fields
Returns the static manifest of indexes available to `search.query` / `search.recent`, including which text fields are scanned, the timestamp column used for ordering, and the underlying table.
scope: read:searchPOST /api/v1/search/policystablereadSearch engine limits, operators, and scoring contract
Returns the public search contract: max query length, max token count, AND-only operator semantics, snippet length, default + max limit, and the deterministic scoring rule (token coverage × recency decay). Safe to cache.
scope: read:searchPOST /api/v1/search/indexstablewriteIndex (or update) a document for cross-entity search
Idempotent on (entityType, entityId). Postgres builds the tsvector automatically with A/B weighting (title vs body).
scope: write:searchPOST /api/v1/search/querystablereadFull-text search across indexed entities
Uses Postgres `plainto_tsquery` ranking. Optionally scope to a single `entityType`.
scope: read:searchPOST /api/v1/search/saved_createstablewriteCreate or update a saved search
Upserts on (userId, name). `pinned` controls list ordering.
scope: write:searchPOST /api/v1/search/saved_liststablereadList saved searches (pinned first)
Pinned entries appear first, then by most recently updated.
scope: read:searchPOST /api/v1/search/saved_deletestablewriteDelete a saved search
Hard delete.
scope: write:searchStatus, SLO & deprecations
POST /api/v1/status/healthstablereadOverall + per-component health summary
Computes an aggregate health status (`operational` | `degraded` | `partial_outage` | `major_outage`) from rolling error rates and latency p95 over the last 15 minutes of `public_api_key_usage`, segmented by pillar and infra component (db, r2, webhooks, rate-limiter). Includes the worst-offending component and a human-readable summary line.
scope: read:statusPOST /api/v1/status/componentsstablereadRegistered components and their live status
Returns every component Dreyv monitors (each pillar + infra: postgres, r2-storage, webhook-dispatcher, rate-limiter, audit-chain) with current status, p50/p95 latency, error rate, sample size, and the SLO they're measured against. Sample window is configurable (default 15m, max 24h).
scope: read:statusPOST /api/v1/status/uptimestablereadRolling uptime % over 1h / 24h / 7d / 30d windows
Derives uptime from `public_api_key_usage` outcomes (`ok` / `rate_limited` count as up; `error` counts as down) bucketed into minute buckets. A minute is `down` if >50% of calls in that minute errored. Returns the up-minute ratio across each window. Aggregate across all callers — Dreyv-wide signal, not per-key.
scope: read:statusPOST /api/v1/status/incidentsstablereadActive and recently-resolved incidents
Detects incidents by scanning the last `lookbackHours` (default 24, max 168) of usage rows for contiguous runs of degraded minutes per component. Returns active incidents (still degraded in the last 5m) and recently-resolved ones with start/end timestamps, impacted component, peak error rate, and affected request count.
scope: read:statusPOST /api/v1/status/slostablereadPer-component SLO targets and live burn rate
Returns the canonical Dreyv SLOs (availability + latency-p95 targets per component) alongside the live 1h and 6h error budget burn rates. A burn rate >1 in either window signals the budget is being consumed faster than the period allows.
scope: read:statusPOST /api/v1/status/deprecationsstablereadCapability deprecation feed with sunset dates
Returns the curated list of deprecated capabilities and fields with announced-at, sunset-at, replacement capability id, and migration notes. Drives the `Sunset` HTTP header and SDK warning toggles. Stable, deterministic — safe to cache.
scope: read:statusPOST /api/v1/status/changelogstablereadPublic API changelog (reverse chronological)
Returns the curated public changelog: every phase release, capabilities added, breaking changes (always called out), security fixes, schema migrations. One canonical feed driving `/developers/api` and the `What's new` banner.
scope: read:statusPOST /api/v1/status/versionstablereadAPI version, capability counts, and build identity
Returns the public API version (`v1`), current capability registry count by pillar/side-effect/status, deprecation count, supported transports, and the build commit (when available via `VERCEL_GIT_COMMIT_SHA`). Useful for SDK compat checks and `If-Match`-style negotiation.
scope: read:statusPOST /api/v1/meta/versionstablereadDreyv MCP server version, tool/pillar counts, and schema metadata
[META] Returns server name + semver, MCP protocol schema version, total tool count, pillar count, scope list, and a sideEffect breakdown (read / unsigned-tx / write / pay). Call this first to know what you're connected to. Includes links to OpenAPI, manifest, REST base, and changelog.
scope: read:statusPOST /api/v1/meta/capabilities_overviewstableread300+ tools mapped to 39 pillars with execution-label tallies
[META] Compact map of every tool grouped by pillar, each tagged with executionLabel (READ / UNSIGNED-TX / WRITE / PAY) so agents know what each call will do before invoking. Filter by pillar or executionLabel to narrow. Safer than tools/list for first-pass discovery.
scope: read:statusPOST /api/v1/meta/intents_howtostablereadEnd-to-end execution playbooks (swap, intents, stake, autonomous pay)
[META] Step-by-step flows for the four execution paths: Jupiter swap, persistent compile→sign→submit intent (multisig-friendly), Marinade SOL stake, and autonomous SKU purchase via dreyv_economy_pay. Includes the non-custodial signing model, preflight tips, and structured error semantics.
scope: read:statusPOST /api/v1/meta/instructionsstablereadServer orientation text (custody model, tool tags, discovery)
[META] Returns the same orientation block we'd return in MCP `initialize.instructions` if the transport supported it: who we are, the [READ]/[UNSIGNED-TX]/[WRITE]/[PAY] tag system, how to discover, how to authenticate.
scope: read:statusJobs & scheduling
POST /api/v1/jobs/schedulestablewriteSchedule a recurring or one-shot capability run
Persists a job that invokes another registered capability on a schedule. `kind:'recurring'` requires `intervalSeconds` (>= tier floor: free 15m / mini 5m / max 1m); `kind:'one_shot'` requires `runAt` (ISO). The payload is validated against the target capability's input schema at schedule time and again at every run. Per-tier active-job quota enforced (free 5 / mini 50 / max 500). Cannot schedule `jobs.*` capabilities (loop guard).
scope: write:jobsPOST /api/v1/jobs/liststablereadList scheduled jobs (optionally filtered)
Returns up to `limit` (default 100, max 500) of the caller's jobs, newest first. Optional filters: `status` (`active` | `paused` | `cancelled` | `completed`) and `capabilityId` (exact match).
scope: read:jobsPOST /api/v1/jobs/getstablereadFetch a single job and (optionally) its recent runs
Returns the full job row plus, when `includeRuns:true`, the most recent run history (up to `runLimit`, default 20, max 200). Strictly scoped to the caller's userId.
scope: read:jobsPOST /api/v1/jobs/cancelstablewriteCancel a scheduled job
Marks the job `cancelled`. Idempotent: a job already in a terminal state (`cancelled` | `completed`) is returned with `alreadyTerminal:true` instead of erroring. Emits the `job.cancelled` webhook and writes a hash-chained audit row.
scope: write:jobsPOST /api/v1/jobs/run_nowstablewriteExecute a job immediately (out-of-band of its schedule)
Synchronously invokes the job's capability with its stored payload and records a `triggered_by:'manual'` run row. Does NOT advance the recurring schedule's `nextRunAt`. Returns the run id, status, duration, and truncated result (<=16 KiB) or error. Emits `job.completed` or `job.failed`.
scope: write:jobsPOST /api/v1/jobs/runsstablereadList job runs across one or all jobs
Returns up to `limit` (default 50, max 500) run rows newest first. Optional filters: `jobId` to scope to a single job, and `status` (`queued` | `running` | `ok` | `failed` | `cancelled`).
scope: read:jobsPOST /api/v1/jobs/retrystablewriteRetry a failed run
Re-executes the same payload as a new attempt (attempt = original + 1) up to the job's `maxRetries`+1 cap. Only runs with `status:'failed'` are eligible. Records a `triggered_by:'retry'` row and emits the same completion/failure webhooks as a scheduled run.
scope: write:jobsPOST /api/v1/jobs/policystablereadScheduler limits, intervals, and trigger taxonomy
Returns the caller's tier, its per-tier job quota and minimum interval, the 30-day interval ceiling, payload (32 KiB) and result-capture (16 KiB) byte limits, the retry ceiling, the valid trigger sources, and the canonical job/run status enums. Stable and cache-safe.
scope: read:jobsExports & reports
POST /api/v1/exports/sourcesstablereadList supported export sources, formats, and columns
Returns the catalog of every data source you can export (audit, usage, deliveries, notifications, watchers, monitors, proposals, jobs, runs, artifacts), the columns each source projects, the read-scope each source effectively requires, and the supported serialization formats (`csv` | `jsonl`). Stable and cache-safe.
scope: read:exportsPOST /api/v1/exports/createstablewriteGenerate a CSV/JSONL export of one of your data sources
Synchronously serializes the caller's rows for the given `source` (filtered by `since` / `until` ISO timestamps and optional `status` / `capabilityId`) into `csv` or `jsonl`. Body stored inline (cap 4 MiB) with sha-256, row count, and `truncated` flag. Per-tier active-export quota enforced (free 5 / mini 50 / max 500) and per-tier row cap (free 5k / mini 50k / max 500k). Emits `export.created` then `export.completed` (or `export.failed`) and writes a hash-chained audit row.
scope: write:exportsPOST /api/v1/exports/liststablereadList your generated exports (metadata only)
Returns up to `limit` (default 100, max 500) of the caller's exports, newest first. Body is NOT included. Filter by `source` or `status` (`pending` | `completed` | `failed` | `purged`).
scope: read:exportsPOST /api/v1/exports/getstablereadFetch a single export's metadata
Returns the full metadata row (label, source, format, status, rowCount, byteSize, sha256, truncated, filters, expiresAt, createdAt, purgedAt) for one export. The body itself is fetched via `exports.download`. Strictly scoped to the caller's userId.
scope: read:exportsPOST /api/v1/exports/downloadstablereadDownload an export body (base64-encoded)
Returns the stored body as base64 along with `contentType` (`text/csv` or `application/x-ndjson`), a safe `filename`, the `sha256`, and `byteSize`. Only `status:'completed'` exports are downloadable; purged (410) and expired (410) exports surface explicit errors. Re-downloads do not advance any quota.
scope: read:exportsPOST /api/v1/exports/purgestablewritePurge an export's body while retaining its metadata
Sets `status:'purged'`, drops the inline body, and stamps `purgedAt`. Metadata (row count, byte size, sha-256, filters) is preserved for auditability. Idempotent — already-purged rows return `alreadyPurged:true`. Writes a hash-chained audit row.
scope: write:exportsPOST /api/v1/exports/statsstablereadAggregate counts and bytes per source/status
Returns per (source, status) totals — count, totalBytes, totalRows — across every export you've ever generated, plus your current tier, active-export quota usage, max-row cap, and TTL.
scope: read:exportsPOST /api/v1/exports/policystablereadExport engine limits, formats, and retention
Returns the caller's tier and its quotas (active exports, max rows, TTL days), the 4 MiB body cap, default TTL, supported formats and sources, and the canonical status enum. Stable and cache-safe.
scope: read:exportsTags, labels & annotations
POST /api/v1/tags/createstablewriteCreate a tag (idempotent on normalized name)
Creates a user-scoped tag with a normalized lowercase `name` (the lookup key), the original-cased `display`, a `color` from the 14-preset palette (default `violet`), and an optional `description` and free-form `metadata`. Idempotent on `(userId, name)`: re-creating returns the existing row with `alreadyExisted:true`. Per-tier tag quota enforced (free 25 / mini 250 / max 2500). Writes a hash-chained audit row.
scope: write:tagsPOST /api/v1/tags/liststablereadList your tags with link counts
Returns up to `limit` (default 200, max 1000) of the caller's tags, newest first, each hydrated with its current `linkCount` (number of entities attached). Optional case-insensitive `query` does a substring match against the normalized name.
scope: read:tagsPOST /api/v1/tags/updatestablewriteUpdate a tag's display, color, description, or metadata
Patches the named/uuid'd tag. `name` (the lowercase lookup key) is immutable — pass a new `display` to relabel without breaking existing links. `color` must come from the preset palette. Writes a hash-chained audit row recording which fields changed.
scope: write:tagsPOST /api/v1/tags/deletestablewriteDelete a tag and cascade-remove its links
Removes the tag and every link attached to it. `id` accepts either the tag uuid or its normalized name. The number of cascaded links is reported as `removedLinks` and recorded in the audit row.
scope: write:tagsPOST /api/v1/tags/attachstablewriteAttach a tag to any entity (idempotent on the triple)
Links the tag to `(entityType, entityId)` with an optional `note` (<= 1000 chars). `entityType` is one of address|tx|capability|job|run|artifact|proposal|watcher|monitor|export|notification|delivery|webhook|custom. `entityId` is opaque text (uuid, numeric id, address, tx hash, capability id, freeform). Idempotent on `(tagId, entityType, entityId)`: a duplicate attach returns the existing row, and a non-null `note` will be updated in-place (`noteUpdated:true`). Per-tag and per-entity quotas enforced.
scope: write:tagsPOST /api/v1/tags/detachstablewriteDetach a tag from an entity
Removes the link for the `(tag, entityType, entityId)` triple. Idempotent: if no such link exists the response is `{ deleted:false, alreadyDetached:true }`. Writes a hash-chained audit row when an actual delete occurs.
scope: write:tagsPOST /api/v1/tags/entitiesstablereadList entities for a tag, or tags for an entity
Two modes. (1) `tag` only → returns up to `limit` entities attached to that tag (`mode:'by_tag'`). (2) `entityType` + `entityId` → returns every tag attached to that entity (`mode:'by_entity'`), with the tag row joined inline. Default limit 200, max 1000.
scope: read:tagsPOST /api/v1/tags/policystablereadTagging engine limits, palette, and entity taxonomy
Returns the caller's tier and its quotas (max tags, max links per tag, max tags per entity), the full 14-color preset palette, the 14-value entity-type taxonomy, and per-field length caps. Stable and cache-safe.
scope: read:tagsFeature flags & experiments
POST /api/v1/flags/createstablewriteCreate a typed feature flag with ordered rules
Creates a user-scoped feature flag. `key` is normalized to a lowercase slug (immutable, unique per user). `type` is one of boolean|string|number|json and is enforced on `defaultValue` and every rule's `value`. `rules` is an ordered list of `{ when: { attr: { op, value } }, value, note? }`; the first rule whose `when` map fully matches the eval context wins. Returns 409 if the key already exists. Tier quotas: free 10 flags / 8 rules, mini 100 / 32, max 1000 / 128. Writes a hash-chained audit row.
scope: write:flagsPOST /api/v1/flags/liststablereadList your flags with rule counts
Returns up to `limit` (default 200, max 1000) of the caller's flags, newest first, each hydrated with `ruleCount`. Archived flags are excluded unless `includeArchived:true`. Optional case-insensitive `query` does a substring match against the normalized key.
scope: read:flagsPOST /api/v1/flags/getstablereadFetch a single flag by uuid or key
Returns the full flag row including its rule list and metadata. `id` accepts either the flag uuid or its normalized key.
scope: read:flagsPOST /api/v1/flags/updatestablewritePatch a flag's display, default, rules, or enabled state
Patches the named/uuid'd flag. `key` and `type` are immutable — re-validates `defaultValue` and every `rules[i].value` against the existing type. Per-tier rule cap re-checked when `rules` is supplied. Writes a hash-chained audit row recording which fields changed.
scope: write:flagsPOST /api/v1/flags/archivestablewriteArchive (soft-disable) or restore a flag
Sets `archivedAt=now()` and forces `enabled=false` so subsequent evaluations always return the default with reason `archived`. Pass `restore:true` to clear `archivedAt` and resume normal evaluation. Audit row written either way.
scope: write:flagsPOST /api/v1/flags/deletestablewritePermanently delete a flag and its evaluation log
Hard-deletes the flag; the cascade also drops every row in the evaluation log. The number of removed evaluation rows is reported as `removedEvaluations` and recorded in the audit row. For non-destructive disable, use `flags.archive`.
scope: write:flagsPOST /api/v1/flags/evaluatestablereadServer-evaluate one flag against a context
Loads the flag and walks its rules in order against `context`. Operators: eq, neq, in, nin, gt, gte, lt, lte, contains, startsWith, endsWith, regex, exists, percent. `percent` buckets via sha256(`${flagKey}:${ruleIndex}` + actual) for stable rollout. Returns `{ value, matchedRule, reason }` where reason is one of `rule_match` | `default` | `disabled` | `archived`. Evaluation is logged unless `log:false`.
scope: read:flagsPOST /api/v1/flags/bulk_evaluatestablereadEvaluate up to 100 flags against a shared context
One-roundtrip evaluation for multiple keys. Returns `{ results: { [key]: { found, value, matchedRule, reason, ... } } }` plus a `missing` list of keys with no matching flag. Same evaluation semantics and logging behavior as `flags.evaluate`.
scope: read:flagsPOST /api/v1/flags/historystablereadRecent evaluations for a flag with rule distribution
Returns up to `limit` (default 100, max 500) of the most recent evaluation rows for the flag, plus a `distribution` map counting how often each `rule_N` (or `default`) was the winning branch. Each row carries the redacted context (<=2KiB) and its canonical sha256 hash for replay comparison.
scope: read:flagsPOST /api/v1/flags/policystablereadFlag-engine limits, types, and operator catalog
Returns the caller's tier and quotas (max flags, max rules per flag, daily evaluation log cap), the four supported types, the full operator catalog, per-field length caps, and evaluation semantics notes. Stable and cache-safe.
scope: read:flagsObservability: traces, spans & metrics
POST /api/v1/obs/trace_ingeststablewriteIngest an OTel-style trace (1 trace, N spans)
Stores a trace and all spans atomically. Idempotent on (userId, traceId): re-ingesting updates the trace summary and adds any missing spans.
scope: write:obsPOST /api/v1/obs/trace_liststablereadList recent traces
Newest-first. Filter by service or status.
scope: read:obsPOST /api/v1/obs/span_liststablereadList spans for a trace (ordered by start time)
Returns every span tied to the trace, ordered by `startNs` ascending.
scope: read:obsPOST /api/v1/obs/metric_ingeststablewriteIngest a batch of metric points (counter/gauge/histogram)
Up to 5000 points per call. Labels are arbitrary JSON.
scope: write:obsPOST /api/v1/obs/metric_querystablereadQuery metric points and aggregate stats over a window
Returns raw points plus min/max/avg/last summary. Default window is the last 24h.
scope: read:obsRate limits & quotas
POST /api/v1/limits/policy_createstablewriteCreate a rate-limit policy (per key, user, route, or IP)
Defines `limitCount` requests per `windowSec` with optional `burst`. `action` chooses what happens on overflow: `throttle`, `reject`, or `log`.
scope: write:limitsPOST /api/v1/limits/policy_liststablereadList rate-limit policies
Newest-updated first.
scope: read:limitsPOST /api/v1/limits/policy_updatestablewriteUpdate a rate-limit policy (partial)
Patch `enabled`, `limitCount`, `windowSec`, `burst`, or `action`.
scope: write:limitsPOST /api/v1/limits/policy_deletestablewriteDelete a rate-limit policy
Cascades to its usage rows.
scope: write:limitsPOST /api/v1/limits/checkstablewriteCheck & consume a rate-limit bucket
Atomically increments the bucket if allowed, returns `{ allowed, limit, remaining, resetAt }`. Buckets are aligned to fixed windows.
scope: write:limitsPOST /api/v1/limits/usagestablereadRecent usage rows for a policy
Newest-first.
scope: read:limitsData residency & region pinning
POST /api/v1/regions/liststablereadList supported regions
Static catalog of region codes you can pin resources to.
scope: read:residencyPOST /api/v1/residency/policy_getstablereadGet the caller's residency policy
Returns the default region, allowed-region list, and strict-mode flag. Returns sensible defaults (with `inherited:true`) if no policy is set.
scope: read:residencyPOST /api/v1/residency/policy_setstablewriteSet the caller's residency policy
Validates regions against the supported list. `defaultRegion` must be in `allowedRegions`. Upserts in place.
scope: write:residencyPOST /api/v1/residency/pinstablewritePin a resource to a specific region
Refuses regions not in the caller's `allowedRegions`. Idempotent on (resourceType, resourceId).
scope: write:residencyPOST /api/v1/residency/pin_liststablereadList pinned resources
Filter by `resourceType` and/or `region`.
scope: read:residencyDigests & multi-channel fan-out
POST /api/v1/digests/channel_createstablewriteCreate a digest channel (slack / telegram / email / webhook)
Stores the channel target plus optional quiet-hours window (`HH:MM` UTC). Use a `secretRef` to point at a stored signing token instead of inlining secrets.
scope: write:digestsPOST /api/v1/digests/channel_liststablereadList digest channels
Filter by `kind` or `enabled` state.
scope: read:digestsPOST /api/v1/digests/channel_deletestablewriteDelete a digest channel
Schedules referencing the channel will skip it on next run.
scope: write:digestsPOST /api/v1/digests/schedule_createstablewriteCreate a digest schedule (cron → channels)
Validates that all `channelIds` belong to the caller and that `cron` has 5 fields. The runner picks up the next-due schedule.
scope: write:digestsPOST /api/v1/digests/schedule_liststablereadList digest schedules
Newest-updated first.
scope: read:digestsPOST /api/v1/digests/send_nowstablewriteSend an immediate digest to a single channel
Respects quiet hours. Records the send intent in the audit log so delivery is traceable.
scope: write:digestsWorkflows & DAG automations
POST /api/v1/workflows/createstablewriteCreate a workflow (trigger → DAG of nodes)
Validates the DAG: unique node ids, all `next` refs resolved, no cycles, ≤100 nodes. Node `kind` ∈ {capability, branch, delay, noop}.
scope: write:workflowsPOST /api/v1/workflows/liststablereadList workflows
Newest-updated first.
scope: read:workflowsPOST /api/v1/workflows/getstablereadGet a workflow by id
Returns the full definition (trigger + nodes).
scope: read:workflowsPOST /api/v1/workflows/deletestablewriteDelete a workflow
Cascades to runs.
scope: write:workflowsPOST /api/v1/workflows/runstablewriteExecute a workflow (topological order, records a run)
Topologically orders nodes, executes them, and stores a `workflow_run` row with per-node log. Capability nodes are queued (not executed inline) so long fan-outs don't block the API call; pass `dryRun:true` to only validate the plan.
scope: write:workflowsPOST /api/v1/workflows/runs_liststablereadList recent workflow runs
Newest-first. Filter by `workflowId` and/or `status`.
scope: read:workflowsEntitlements & plan enforcement
POST /api/v1/entitlements/liststablereadList every feature, its plan value, and active override
Returns the caller's tier plus a per-feature breakdown: `planValue`, `override`, `effectiveValue`, `source`.
scope: read:entitlementsPOST /api/v1/entitlements/checkstablereadCheck whether a feature is allowed (optionally with a requested numeric value)
For boolean features, returns the value. For numeric features, returns `allowed = requestedValue ≤ effectiveValue`.
scope: read:entitlementsPOST /api/v1/entitlements/override_setstablewriteSet or update an entitlement override (optionally time-boxed)
Upserts on (userId, feature). `value` can be boolean, number, string, or object. `expiresAt` makes the override temporary.
scope: write:entitlementsPOST /api/v1/entitlements/override_liststablereadList active entitlement overrides
Newest-updated first. Expired overrides remain visible so you can clean them up.
scope: read:entitlementsPOST /api/v1/entitlements/override_deletestablewriteDelete an entitlement override
Subsequent checks fall back to the plan value.
scope: write:entitlementsRoadmap
Phases 1 to 31 shipped pillars A through AO (identity, portfolio, market, execution, forensics, agentic, storage, jobs, exports, tags, flags, inbox, teams, billing, insights, marketplace, SLA, contracts). Phases 32 to 39 add pillars AP to AX: observability with OTel-style traces and metrics, a hash-chained audit log with SOC2/GDPR evidence bundles, configurable rate-limit policies, data residency and region pinning, multi-channel digests (Slack/Telegram/email/webhook) with quiet hours, cross-entity full-text search with saved queries, a workflow DAG engine with topologically ordered runs, and plan-aware entitlements with per-user overrides.