The Response Envelope

Every OASIS API response — success or failure — is wrapped in the same envelope:

json
{
  "result":         null,
  "isError":        true,
  "isWarning":      false,
  "message":        "A username with that name already exists.",
  "detailedMessage": "Duplicate username: david"
}
🔴
Do not rely solely on HTTP status codes

OASIS returns HTTP 200 for many business-logic failures. Always inspect isError first before consuming result.

isError vs isWarning

FlagMeaningAction
isError: false, isWarning: falseFull successConsume result normally
isError: false, isWarning: truePartial success — something non-fatal happenedConsume result, surface message to the user if relevant
isError: trueHard failure — result will be nullShow message to the user, do not consume result

Common Error Messages

messageCauseFix
A username with that name already exists.Duplicate username on register or updatePrompt user to choose a different username
A avatar with that email already exists.Duplicate email on register or updateOffer login or password-reset flow
Email has not been verified.Login attempted before verificationRe-send verification email
Username or password is incorrect.Bad credentials on authenticateShow generic auth error to user
UnauthorizedMissing or expired JWTRe-authenticate and retry with a fresh token
Avatar not found.ID doesn't exist or was soft-deletedVerify the avatar ID is correct
An unknown error has occurred.Unhandled server exceptionCheck detailedMessage; report to OASIS support

HTTP Status Codes

CodeMeaning
200Request was received and processed — check isError for outcome
400Malformed request — missing required fields or invalid JSON
401No or invalid Authorization header
403Authenticated but not permitted (e.g. non-admin accessing admin endpoint)
404Route not found — check the endpoint path
500Unhandled server error — retry with backoff; contact support if persistent

Recommended Handling Pattern

javascript
async function oasisRequest(url, options = {}) {
  const res = await fetch(url, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`,
      ...options.headers
    }
  });

  if (!res.ok) throw new Error(`HTTP ${res.status}`);

  const envelope = await res.json();

  if (envelope.isError) {
    throw new Error(envelope.message || 'OASIS error');
  }

  if (envelope.isWarning) {
    console.warn('[OASIS]', envelope.message);
  }

  return envelope.result;
}