Skip to main content
These are the cross-cutting rules. Read them once; they apply to every endpoint.

Base URL

https://hubra.app/api/v1

Content type

Every request and successful response uses application/json.
Content-Type: application/json
Errors use application/problem+json (RFC 9457). See Errors for the format.

Decimal amounts

All amounts are passed and returned as decimal strings, not floats.
{ "amount": "1.5" }
{ "outAmount": "1.7234" }
This avoids IEEE-754 drift and matches the precision the on-chain stake program enforces. Numeric strings are parsed by the server with full precision; floats are not safe. The on-chain math itself happens in lamports (1 SOL = 10⁹ lamports) or USDC’s smallest unit (10⁶), but you never need to do that conversion: pass "1.5", get back "1.7234", and the server handles the unit math.

Versioning

Every response includes:
X-Hubra-Api-Version: v1
Breaking changes ship as /api/v2. The v1 surface is committed to API stability for the duration of its deployed life.

CORS

Read endpoints (GET) accept any origin:
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Authorization, Content-Type, Idempotency-Key
Access-Control-Allow-Methods: GET, POST, OPTIONS
Write endpoints accept the same. Tighter origin policy may be applied per-route in future versions. Preflights (OPTIONS) return 204 with the same headers and an empty body.

HTTP methods

MethodUsed for
GETPublic reads (strategies, APY history, health)
POSTAll writes; also any read that takes a request body (e.g., quotes)
OPTIONSCORS preflight
There is no PUT, PATCH, or DELETE in the v1 surface.

Caching

Read endpoints are force-dynamic server-side (no Next.js caching of the response). Upstream data (Sanctum APY, validator APY, Voltr stats) has its own cache windows; expect those to refresh on the order of a few minutes. If you need the freshest possible APY, hit /api/v1/strategies directly rather than reading from a cached client.

Error format

Errors follow RFC 9457 problem-details:
{
  "type":    "https://hubra.app/errors/invalid_request",
  "title":   "Invalid request",
  "status":  400,
  "detail":  "Required fields: strategy, wallet, amount."
}
Branch on type, not on title. The type slug is stable; the title is human-friendly and may evolve. See Errors for the full slug list.

Rate limiting

There is currently no rate limit on the v1 surface. As the API matures, per-IP soft limits will be applied. When that ships, responses will include RateLimit-* headers (RFC 9331). For high-volume callers, contact hello@hubra.app to discuss.

Idempotency

Write endpoints accept Idempotency-Key: <uuid> and replay the same response for that key within a 24-hour window. This matters for agent retries, where a network blip might cause a double-build of the same transaction.
curl -X POST https://hubra.app/api/v1/stake \
  -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"strategy":"sol-native-stake","wallet":"<wallet>","amount":"1.0"}'

Authentication

There is none on the v1 surface. The on-chain signature on the actual stake transaction is the only authorization that matters. Any caller can build an unsigned transaction; only the wallet that owns the input asset can sign it. If a future version adds API keys, the auth header will be:
Authorization: Bearer hbr_live_<22 base58>
For now, the header is unused.

Partner attribution

Hubra partners (protocols, devs, creators) can identify themselves on stake calls so the liquidity they bring in is credited to their account. This is not authentication — it’s attribution, and it’s entirely optional. Pass your partner API key (from partner.hubra.app) on POST /api/v1/stake, either as a partner_api_key body field or an X-Partner-Key header:
X-Partner-Key: hbr_pk_<your-key>
The first partner to bring a given wallet in keeps the credit (first-write-wins). An invalid or inactive key returns 403 forbidden.

What’s next

Strategies

The strategy registry.

Errors

Problem-details and how to branch on slug.

Hubra token

The HMAC gate on /broadcast.

Glossary

Solana / staking terminology.