Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.hubra.app/llms.txt

Use this file to discover all available pages before exploring further.

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.

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.