Skip to content
Docs navigation: System Zero / Workspaces and keys

Workspaces and keys

DocsSystem ZeroWorkspaces and keys Updated

A workspace groups your API keys, usage, limits and Playground.

decide.sh
# Set SYSTEM_ZERO_API_KEY to your API key before running this example.
# Generate once per logical decision; reuse this key when retrying.
idempotency_key="$(uuidgen 2>/dev/null \
  || cat /proc/sys/kernel/random/uuid 2>/dev/null \
  || openssl rand -hex 16 2>/dev/null \
  || python3 -c 'from uuid import uuid4; print(uuid4())' 2>/dev/null)"
cat > request.json <<'EOF'
{
  "model": "system-zero",
  "state": "The blender I ordered arrived with a cracked jar.",
  "questions": {
    "damaged": {
      "type": "boolean",
      "instructions": "Did the item arrive damaged?"
    }
  }
}
EOF
# Headerless error responses require Python 3 to read error.code.
# If x-should-retry is present, resend only when x-should-retry is true. If the
# header is absent, resend on 429, or on 409 and 5xx only with a retryable
# error.code. No answer also retries. Wait Retry-After plus up to 10 %,
# otherwise a random wait doubling from 1 s to 30 s. Stop if Retry-After is over
# 60 s. Also stop when a 429 has no Retry-After, or a 5xx has x-should-retry but
# no Retry-After.
random() { od -An -N4 -tu4 /dev/urandom | tr -d ' '; }
# Stop resending after 10 minutes.
start=$(date +%s) attempt=0
while :; do
  : "${SYSTEM_ZERO_API_KEY:?set it first}"
  : "${idempotency_key:?could not make one}"
  rm -f reply.json
  out=$(curl https://api.rightnowai.co/v1/system-zero/decide \
    --max-time 130 -sS -o reply.json -D - -w '%{http_code}' \
    -H "Authorization: Bearer $SYSTEM_ZERO_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $idempotency_key" \
    -d @request.json)
  code=$(printf '%s' "$out" | tail -c 3)
  retry_header=$(printf '%s\n' "$out" \
    | grep -i '^x-should-retry:' | tail -n 1)
  retry=$(printf '%s\n' "$retry_header" \
    | sed 's/^[^:]*:[[:space:]]*//;s/[[:space:]]*$//')
  after=$(printf '%s\n' "$out" | grep -i '^retry-after:' \
    | tail -n 1 | sed 's/^[^:]*:[[:space:]]*//;s/[[:space:]]*$//')
  case $after in *[!0-9]*|'') after= ;; esac
  if [ -z "$retry_header" ]; then
    case $code in
      000|429) ;;
      409|5??)
        error_code=$(python3 -c 'import json, sys
try:
    print(json.load(sys.stdin).get("error", {}).get("code", ""))
except (ValueError, AttributeError):
    pass' < reply.json 2>/dev/null) || break
        case $code:$error_code in
          409:idempotency_conflict) ;;
          409:upload_in_use) ;;
          409:session_busy) ;;
          5??:service_unavailable) ;;
          5??:system_zero_unavailable) ;;
          5??:billing_settlement_error) ;;
          5??:idempotency_unavailable) ;;
          5??:limiter_unavailable) ;;
          5??:internal_error) ;;
          5??:maintenance) ;;
          5??:revoke_notice_unavailable) ;;
          *) break ;;
        esac ;;
      *) break ;;
    esac
  else
    [ "$retry" = true ] || break
    case $code in 4??|5??) ;; *) break ;; esac
  fi
  if [ -n "$after" ]; then
    after=$(printf '%s' "$after" | sed 's/^0*//')
    after=${after:-0}
    [ "$after" -le 60 ] || break
    ms=$(( after * 1000 + $(random) % (after * 100 + 1) ))
  else
    [ "$code" != 429 ] || break
    if [ -n "$retry_header" ]; then
      case $code in 5??) break ;; esac
    fi
    cap=$(( attempt < 5 ? 1000 << attempt : 30000 ))
    ms=$(( $(random) % (cap + 1) ))
  fi
  [ $(( $(date +%s) - start + ms / 1000 )) -lt 600 ] || break
  sleep "$(( ms / 1000 )).$(printf '%03d' $(( ms % 1000 )))"
  [ $(( $(date +%s) - start )) -lt 600 ] || break
  attempt=$(( attempt + 1 ))
done
echo "HTTP $code"
cat reply.json 2>/dev/null

Keys and usage

Create a named key under API keys and copy it when it appears. The key and its calls belong to that workspace. See Authentication for the header and Rate limits for refusals.

Usage separates answered decisions, replays, failed calls and unavailable calls. Recent requests show metadata such as the request ID, status and error code; they do not show the request content or answer.

Roles

RoleActions
All rolesRead the workspace, run Playground, create keys, revoke their own keys and leave.
Owners and adminsRevoke any key, manage invitations, rename the workspace and remove ordinary members.
OwnersRemove privileged members, change roles and schedule workspace deletion.

A workspace must keep an owner.

Invitations

Owners and admins manage invitations. Sign in to the console to use the actions available to your role.

Cancel and restore

An owner can schedule workspace deletion in Settings after signing in again. Keys and open invitations are revoked. Restoring the workspace leaves those keys revoked.

Deleting a workspace does not delete your sign-in identity. Use the privacy policy for identity deletion and personal-record requests.