Error Codes

All error codes returned by the GPCN™ API, including their HTTP status, what they mean, and how to resolve them.

Error Response Format

All errors follow this structure:

{
  "success": false,
  "error": "ERROR_CODE",
  "message": "Human-readable description of the error"
}

Use the error field for programmatic matching. The message field is for logging and debugging.

Error Code Reference

INVALID_CREDENTIALS

HTTP Status 401 Unauthorized
Description The email or password provided is incorrect.

Common causes:

  • Typo in email address or password
  • Account doesn't exist
  • Account has been deleted

Solution: Double-check your email and password. If you've forgotten your password, use the password reset flow via POST /auth/forget-password.

TWO_FACTOR_REQUIRED

HTTP Status 400 Bad Request
Description Credentials are valid, but 2FA verification is needed to complete sign-in.

Common causes:

  • This is expected behavior, not an error. All GPCN™ accounts require 2FA.

Solution: Complete the 2FA flow. Check the totpConfigured field in the response to determine whether to use TOTP (POST /auth/two-factor/verify-totp) or email OTP (POST /auth/two-factor/send-otp followed by POST /auth/two-factor/verify-otp).

INVALID_OTP

HTTP Status 400 Bad Request
Description The 2FA code provided is incorrect or expired.

Common causes:

  • Typo in the 6-digit code
  • Code has expired (TOTP codes rotate every 30 seconds)
  • Email OTP has expired
  • Clock on your authenticator device is out of sync

Solution: Try entering the code again. For TOTP, wait for the next code to generate. For email OTP, request a new code via POST /auth/two-factor/send-otp. If your authenticator clock is off, sync it in your device settings.

SESSION_EXPIRED

HTTP Status 401 Unauthorized
Description Your session has expired due to inactivity or timeout.

Common causes:

  • Session timed out after extended inactivity
  • Server-side session was invalidated (e.g., after a password change)
  • Session cookie was cleared

Solution: Sign in again via POST /auth/sign-in/email. For API integrations, consider using API keys instead of sessions — they don't expire from inactivity.

NOT_AUTHENTICATED

HTTP Status 401 Unauthorized
Description No valid authentication was provided with the request.

Common causes:

  • Missing X-API-Key header or session cookie
  • Malformed Authorization header
  • Request sent to an authenticated endpoint without credentials

Solution: Include authentication with your request. Use X-API-Key for programmatic access, session cookies for browser requests, or Authorization: Bearer for token-based auth.

INSUFFICIENT_PERMISSIONS

HTTP Status 403 Forbidden
Description You're authenticated, but your role doesn't grant the required permission for this action.

Common causes:

  • Your role doesn't include the needed permission for this action
  • You're trying to access a resource in a different entity
  • The operation requires a higher-privilege role

Solution: Check your current permissions via GET /auth/check. Ask your administrator to assign a role with the required permission.

API_KEY_INVALID

HTTP Status 401 Unauthorized
Description The API key provided doesn't exist or has been revoked.

Common causes:

  • Typo in the API key value
  • Key was deleted or suspended
  • Key was rotated (old value is no longer valid)
  • Key belongs to a deleted user

Solution: Verify the key value is correct. Check if the key has been suspended via the dashboard. If the key was rotated, use the new key value. Create a new key if needed via POST /auth/api-keys/me.

API_KEY_EXPIRED

HTTP Status 401 Unauthorized
Description The API key has passed its expiration date.

Common causes:

  • Key was created with an expiration date that has now passed

Solution: Create a new API key via POST /auth/api-keys/me. Consider using a longer expiration period or a non-expiring key if appropriate for your use case.

RATE_LIMIT_EXCEEDED

HTTP Status 429 Too Many Requests
Description You've made too many requests in a short period.

Common causes:

  • Sending requests faster than the rate limit allows
  • Multiple API keys for the same user sharing a rate limit pool
  • Tight polling loops without delay
  • Burst of requests during retry storms

Solution: Check the X-RateLimit-Reset header for when you can retry. Implement exponential backoff in your retry logic. See Rate Limiting for optimization strategies.

INVALID_REQUEST

HTTP Status 400 Bad Request
Description The request body or query parameters are malformed or fail validation.

Common causes:

  • Missing required fields in the request body
  • Invalid field types (e.g., string where number is expected)
  • Unknown fields in the request body (strict validation rejects them)
  • Invalid UUID format for ID fields
  • Value out of allowed range

Solution: Check the message field for details about which field failed validation. Ensure your request body includes all required fields with correct types. Don't include extra fields — the API uses strict validation.

SERVER_ERROR

HTTP Status 500 Internal Server Error
Description Something went wrong on the server side.

Common causes:

  • Transient infrastructure issue
  • Bug in the API (rare)
  • Upstream cloud provider error

Solution: Retry the request after a brief delay. If the error persists, contact GPCN™ support with the request details (endpoint, method, timestamp) so the team can investigate.

Quick Reference Table

Error Code Status Summary
INVALID_CREDENTIALS 401 Wrong email or password
TWO_FACTOR_REQUIRED 400 2FA verification needed
INVALID_OTP 400 Wrong or expired 2FA code
SESSION_EXPIRED 401 Session timed out
NOT_AUTHENTICATED 401 No auth credentials provided
INSUFFICIENT_PERMISSIONS 403 Role lacks required permission
API_KEY_INVALID 401 API key doesn't exist or was revoked
API_KEY_EXPIRED 401 API key past its expiration date
RATE_LIMIT_EXCEEDED 429 Too many requests
INVALID_REQUEST 400 Validation error in request
SERVER_ERROR 500 Internal server error

Handling Errors in Code

Every GPCN™ API error returns a JSON body with success: false and an error code you can match on programmatically:

response=$(curl -s -w "\n%{http_code}" \
  -H "X-API-Key: gpcn_your_api_key_here" \
  https://api.gpcn.com/v1/resource/virtual-machines)
http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d')
if [ "$http_code" -ge 400 ]; then
  error=$(echo "$body" | jq -r '.error')
  message=$(echo "$body" | jq -r '.message // empty')
  echo "Error $http_code: $error$message" >&2
fi

See the API Reference → for examples in TypeScript, Python, Go, and C#.

Next Steps