Error codes
The Northstake API returns errors in a consistent envelope:
{
"success": false,
"error": "<short human-readable message>",
"code": "<machine-readable code, when applicable>"
}The OpenAPI spec (components.schemas.ErrorResponse) is the canonical reference for the wire shape.
HTTP status codes
| Status | Meaning |
|---|---|
200 / 201 | Success |
400 | Client error: malformed request, validation failure |
401 | Unauthenticated |
403 | Forbidden: wrong role, MFA required, or terms not accepted |
404 | Resource not found |
409 | Conflict: e.g. duplicate webhook URL, address already on allowlist |
429 | Rate limited |
500 | Server error |
Authentication / authorization codes
| Code | When |
|---|---|
EXPIRED_TOKEN | The access token has expired |
TOS_NOT_ACCEPTED | The account hasn't accepted current terms |
MFA_REQUIRED | The operation needs step-up MFA |
INSUFFICIENT_ROLE | The caller's account lacks the required scope (e.g. not Pro) |
On-chain / contract-level codes
These come from parsing reverts on the partial-transaction submission path.
| Code | When |
|---|---|
VAULT_REPORT_STALE | settle-lido-fees called against a stale vault-hub report |
ROLE_MISSING | The signing wallet doesn't hold the required on-chain role |
ALLOWLIST_EXISTS | Adding an address already on the allowlist |
ALLOWLIST_NOT_FOUND | Removing an address not on the allowlist |
The contract-error parser lives in the frontend at utils/contractErrors.ts and exposes helpers like isVaultReportStaleError.
Webhook / step-up specifics
| Code | When |
|---|---|
STEP_UP_REQUIRED | Operation needs step-up MFA (matches x-mfaApiScope on the operation) |
STEP_UP_EXPIRED | Step-up token has expired |
Field validation rules
These rules surface as 400 errors when violated.
| Field type | Rule |
|---|---|
| Ethereum address | /^0x[a-fA-F0-9]{40}$/ |
| Basis points | Integer, 0 to 10000 |
minDelaySeconds, minWithdrawalDelayTime, confirmExpiry | UI minimum 1 day (86,400 seconds); below-minimum values rejected by the SVM proxy even if the contract would accept them |
Webhook url | Must begin with https:// |
Idempotency
The API doesn't expose first-class idempotency keys.
- For obviously idempotent ops (e.g. adding the same address twice): the API returns
409/ALLOWLIST_EXISTS. Treat as success. - For on-chain mutations: the transaction hash is the natural dedupe key. The API returns the same partial transaction for the same logical request if called twice within the same nonce window.
- For webhook subscriptions: list before creating; check
url+eventTypesfor an existing match.
Updated about 4 hours ago
