Skip to main content

API Overview

The MAGMA REST API is the canonical way to read protocol data and submit state-changing actions — backing narratives, opening borrow positions, routing capital into DeFi yield, and verifying identity. It is a JSON-over-HTTPS API. All state-changing operations that touch funds are client-signed: the backend builds an unsigned Solana transaction, your client signs it with the user's wallet, and you submit the signature back for on-chain verification.

Beta on Solana devnet

MAGMA is in beta on Solana devnet. Money-movement endpoints build real devnet transactions where the underlying protocol has a devnet market (Kamino, Save) and otherwise return a coming_soon / *_disabled status until mainnet. See DeFi for per-protocol availability.

Base URL

All endpoints are served under a single host:

https://api.magmaprotocol.xyz

There is no separate sandbox host — the beta API already targets devnet.

Versioning

The API is versioned by URL prefix. The current version is v1:

https://api.magmaprotocol.xyz/v1/narratives
PrefixPurpose
/v1/...All public and wallet-signed product routes (narratives, narrative-groups, conviction, missions, DeFi, staking, borrow, verify, KYC, intents, sideshift, tron, users, notifications, terms, waitlist, NFT, shield, binary, agents).
/v1/admin/..., /admin/narratives/...Versioned admin / operations routes (require admin credentials).
/admin, /admin/queuesLegacy operations surface at the root (admin dashboard, BullMQ monitor).
/v1/system/status, healthOperational status and health probes.
note

Breaking changes ship under a new prefix (e.g. a future /v2). Additive changes — new fields, new endpoints — are made in place under /v1. Treat unknown JSON fields as forward-compatible and ignore them.

Request conventions

  • Transport: HTTPS only. Plain HTTP is not served.
  • Content type: request bodies are JSON; send Content-Type: application/json. The maximum request body size is 1 MiB.
  • Methods: GET for reads, POST for writes and transaction preparation, PUT for full updates (e.g. profile), DELETE for removals.
  • Wallet addresses are Solana base58 public keys and usually appear as a path segment (/v1/conviction/:wallet) or a body field (wallet_address).
  • Amounts: SOL amounts are passed either as UI decimals (amount_sol, amount_ui) or as base units / lamports (amount_lamports, amount_base, amount_raw) depending on the endpoint — each is documented per-route. 1 SOL = 1,000,000,000 lamports.

A minimal read request needs no headers beyond the host:

curl 'https://api.magmaprotocol.xyz/v1/defi/apys'

Response conventions

Responses are JSON. Most successful product responses include a top-level boolean ok:

{ "ok": true, "wallet": "7xKX…9fПb", "positions": [] }

Some legacy read endpoints return the payload directly (for example the narrative feed returns { "narratives": [ … ] } and a conviction profile returns the profile object at the top level). Endpoints that prepare a transaction return a transaction (base64) plus a status such as ready_to_sign or ready_to_confirm.

Errors use a consistent envelope and HTTP status codes — see Errors.

AspectConvention
EncodingUTF-8 JSON
Success flagok: true on most product routes
TimestampsISO 8601 UTC (e.g. 2026-04-09T12:00:00Z)
IdentifiersUUID v4 strings for narratives, backings, positions
Moneylamports / base units for precision; UI decimals where noted
Unsigned txbase64-encoded Solana transaction in transaction

Conventions

A handful of contract rules apply across the whole API. They are easy to get wrong and worth fixing in your client once, globally:

  • No .data wrapper. Every MAGMA response returns its fields at the top level. There is no { "data": … } envelope to unwrap — read response.json() directly (e.g. apys, narratives, positions are top-level keys).
  • Single-object reads may wrap once. A few single-resource reads nest the object under a named key. In particular, GET /v1/narratives/:id returns { "narrative": { … } }, so you must unwrap it: const n = data.narrative ?? data. Likewise GET /v1/narrative-groups/:id returns { "group": { … } } and GET /v1/narratives/:id/rules returns { "rules": { … } }.
  • APY values are already percentages. Fields like the apys map from GET /v1/defi/apys are expressed in percent (e.g. 9.2 means 9.2% APY). Never multiply by 100 — render them as-is.
  • score === 0 means PENDING. A narrative score of exactly 0 is not a real zero score; it signals that scoring has not completed. Render it as a placeholder (e.g. an em dash ), not as the number 0.
  • Pre-market gating. A narrative may exist before its market opens (is_pre_market: true, with an opens_at timestamp). Writes against a pre-market narrative — e.g. POST /v1/narratives/:id/back — return 403 { "error": "market_not_open", "opens_at": "<ISO>" }. Gate your UI on is_pre_market and surface opens_at.
  • coming_soon / *_disabled gates. Endpoints whose underlying market, vault, or integration is not wired on devnet return a 503 with a status field such as coming_soon, borrow_disabled, or p0_disabled, or expose a boolean flag (borrow_enabled, vault_deployed) you can pre-check. See Errors for the full code list.

Resource map

ResourceBase pathWhat it doesReference
Narratives/v1/narrativesFeed, originality checks, AI/voice polish, mint preparation, publishing, backing, pre-market gateNarratives
Narrative Groups/v1/narrative-groupsGrouped markets with live volume / backer aggregatesNarrative Groups
Conviction/v1/convictionConviction profile, multipliers, fees, streaks, echo-pool, epochsConviction
Missions/v1/missionsPer-wallet missions, completion checks, leaderboardMissions
DeFi/v1/defiProtocol APYs, deposits/withdrawals (Kamino, Save, Jito, Marinade, P0), allocation, yieldDeFi
Staking/v1/stakingMAGMA staking position and tier for a walletStaking
Borrow/v1/borrowRates, capacity, simulation, prepare/confirm, repay, fast actionsBorrow
Verify/v1/verifyIdentity verification status and flows (Civic, Gitcoin, SAS)Verify
KYC/v1/kycPersona identity verification, status, wallet screeningKYC
NEAR Intents/v1/intentsCross-chain swaps via NEAR Intents (tokens, quote, confirm, status)NEAR Intents
SideShift/v1/sideshiftProxied SideShift cross-chain swaps (coins, quote, shift)SideShift
TRON / Wormhole/v1/tronTRON bridge config and Wormhole VAA statusTRON / Wormhole
Users/v1/usersProfile, transactions, backings, payouts, portfolio, path choiceUsers
SAS Attestations/v1/verify/sasSolana Attestation Service tier badges for a walletSAS Attestations
Notifications/v1/notificationsIn-app feed, read state, and Web Push subscriptionNotifications
Terms/v1/termsAccept and check Terms of ServiceTerms
Waitlist/v1/waitlistPublic waitlist join and statsWaitlist
NFT/v1/nftTier NFT verify / mint / score / transfer webhooksNFT
Shield/v1/shieldProtocol-cover positions and abuse-probe loggingShield
System/v1/systemOperational status probeSystem
Binary Markets/v1/binaryYES/NO markets REST surface (503 — coming post-TGE)Program & API
Agents/v1/agentMachine-readable feed and automation for AI agents / botsAgents

For the full per-endpoint reference, see API Reference. For Web Push subscription and NFT transfer webhooks, see Webhooks.

Pagination

List endpoints use a limit + offset/page convention rather than cursors:

  • limit — page size. Defaults vary by endpoint (commonly 20 for feeds, 50 for transaction history) and are capped server-side (e.g. 1–100 for the narrative feed, 200 for transaction history). Values above the cap are clamped, not rejected.
  • page — 1-based page index on endpoints that paginate by page (for example GET /v1/users/:wallet/backings), which return a total count alongside the rows so you can compute the number of pages.
# Page 2 of a wallet's backings (20 per page)
curl 'https://api.magmaprotocol.xyz/v1/users/<wallet>/backings?page=2'
{
"backings": [ /* up to 20 items */ ],
"total": 47,
"total_backed_sol": 18.4
}
tip

Read endpoints are safe to poll, but respect rate limits. When you need a continuous stream of new narratives for automation, use the Agents feed rather than tight polling of the public feed.

Next steps