Response Formats

Understanding API Response Structures

Learn about mindzieAPI response formats, status codes, error handling patterns, and data structures to build robust integrations.

Standard Response Format

All mindzieAPI responses follow consistent JSON formatting with predictable structures:

Successful Response

{
  "data": {
    // Primary response data
  },
  "metadata": {
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "req_12345",
    "version": "1.0.0"
  },
  "pagination": {
    // Present for paginated responses
    "currentPage": 1,
    "totalPages": 5,
    "totalItems": 100,
    "itemsPerPage": 20,
    "hasNext": true,
    "hasPrevious": false
  }
}

Error Response

{
  "error": {
    "code": "validation_failed",
    "message": "Request validation failed",
    "details": {
      "field": "datasetId",
      "reason": "Invalid GUID format"
    },
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "req_12345"
  }
}

Response Types

Success Responses

HTTP 2xx status codes with structured JSON data and metadata.

Error Responses

HTTP 4xx/5xx status codes with detailed error information.

Pagination

Consistent pagination format for large dataset responses.

HTTP Status Codes

Success Codes (2xx)

Code Status Description Usage
200 OK Request successful, data returned GET requests, successful operations
201 Created Resource successfully created POST requests creating new resources
202 Accepted Request accepted for async processing Long-running operations, queued tasks
204 No Content Request successful, no data returned DELETE requests, updates without return data

Client Error Codes (4xx)

Code Status Description Common Causes
400 Bad Request Invalid request format or parameters Missing headers, invalid JSON, malformed data
401 Unauthorized Authentication required or failed Missing/invalid token, expired credentials
403 Forbidden Valid auth but insufficient permissions Limited user access, wrong tenant/project
404 Not Found Requested resource doesn't exist Invalid endpoint, non-existent resource ID
422 Unprocessable Entity Valid format but business logic validation failed Invalid business rules, constraint violations
429 Too Many Requests Rate limit exceeded Too many API calls in time window

Server Error Codes (5xx)

Code Status Description Action
500 Internal Server Error Unexpected server error Retry with exponential backoff
502 Bad Gateway Upstream service error Check service status, retry later
503 Service Unavailable Service temporarily unavailable Retry after delay, check maintenance
504 Gateway Timeout Request timeout Increase timeout, optimize request

Common Response Patterns

Single Resource Response

{
  "actionId": "87654321-4321-4321-4321-210987654321",
  "actionType": "analyze",
  "status": "completed",
  "startTime": "2024-01-15T10:30:00Z",
  "endTime": "2024-01-15T10:32:15Z",
  "duration": 135,
  "result": {
    "outputId": "98765432-8765-4321-4321-987654321098",
    "recordsProcessed": 10000
  }
}

Collection Response with Pagination

{
  "actions": [
    {
      "actionId": "87654321-4321-4321-4321-210987654321",
      "actionType": "analyze",
      "status": "completed"
    },
    {
      "actionId": "11111111-2222-3333-4444-555555555555",
      "actionType": "export",
      "status": "processing"
    }
  ],
  "pagination": {
    "currentPage": 1,
    "totalPages": 5,
    "totalItems": 100,
    "itemsPerPage": 20,
    "hasNext": true,
    "hasPrevious": false,
    "links": {
      "first": "/api/Action/history?page=1&limit=20",
      "next": "/api/Action/history?page=2&limit=20",
      "last": "/api/Action/history?page=5&limit=20"
    }
  }
}

Async Operation Response

{
  "operationId": "op_12345678-1234-1234-1234-123456789012",
  "status": "processing",
  "progress": {
    "percentage": 45,
    "currentStep": "data_analysis",
    "totalSteps": 5,
    "estimatedCompletion": "2024-01-15T10:35:00Z"
  },
  "trackingUrl": "/api/Execution/status/op_12345678-1234-1234-1234-123456789012",
  "message": "Processing dataset analysis..."
}

Error Response Details

Validation Error

{
  "error": {
    "code": "validation_failed",
    "message": "Request validation failed",
    "details": {
      "errors": [
        {
          "field": "datasetId",
          "code": "invalid_format",
          "message": "Must be a valid GUID"
        },
        {
          "field": "parameters.timeout",
          "code": "out_of_range",
          "message": "Must be between 1 and 3600 seconds"
        }
      ]
    },
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "req_12345"
  }
}

Authentication Error

{
  "error": {
    "code": "invalid_token",
    "message": "The provided access token is invalid or expired",
    "details": {
      "tokenType": "bearer",
      "expiresAt": "2024-01-15T09:00:00Z",
      "suggestion": "Please refresh your access token"
    },
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "req_12345"
  }
}

Rate Limiting Error

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded for this endpoint",
    "details": {
      "limit": 100,
      "remaining": 0,
      "resetTime": "2024-01-15T11:00:00Z",
      "retryAfter": 1800
    },
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "req_12345"
  }
}

Response Headers

Standard Headers

Header Description Example
Content-Type Response format application/json; charset=utf-8
X-Request-Id Unique request identifier req_12345678
X-Response-Time Server processing time 145ms
X-API-Version API version used 1.0.0

Rate Limiting Headers

Header Description Example
X-RateLimit-Limit Maximum requests per window 100
X-RateLimit-Remaining Remaining requests in window 95
X-RateLimit-Reset Window reset timestamp 1642251600
Retry-After Seconds to wait before retry 3600

Best Practices for Error Handling

JavaScript Example

async function handleAPIResponse(response) {
  // Check if response is ok
  if (!response.ok) {
    const errorData = await response.json();

    switch (response.status) {
      case 400:
        throw new ValidationError(errorData.error.message, errorData.error.details);
      case 401:
        throw new AuthenticationError('Authentication failed');
      case 403:
        throw new AuthorizationError('Insufficient permissions');
      case 404:
        throw new NotFoundError('Resource not found');
      case 429:
        const retryAfter = response.headers.get('Retry-After');
        throw new RateLimitError(`Rate limited. Retry after ${retryAfter} seconds`);
      case 500:
      case 502:
      case 503:
      case 504:
        throw new ServerError('Server error occurred. Please retry.');
      default:
        throw new APIError(`Unexpected error: ${response.status}`);
    }
  }

  return await response.json();
}

// Usage with retry logic
async function apiCallWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      return await handleAPIResponse(response);
    } catch (error) {
      if (error instanceof RateLimitError) {
        const retryAfter = parseInt(error.retryAfter) || Math.pow(2, attempt);
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }

      if (error instanceof ServerError && attempt < maxRetries) {
        const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }

      throw error;
    }
  }
}

Python Example

import requests
import time
from typing import Dict, Any

class APIError(Exception):
    def __init__(self, message: str, status_code: int = None, details: Dict = None):
        super().__init__(message)
        self.status_code = status_code
        self.details = details

def handle_api_response(response: requests.Response) -> Dict[str, Any]:
    """Handle API response with proper error handling"""

    if response.ok:
        return response.json()

    try:
        error_data = response.json()
    except ValueError:
        error_data = {"error": {"message": response.text}}

    error_info = error_data.get("error", {})
    message = error_info.get("message", f"HTTP {response.status_code}")
    details = error_info.get("details", {})

    if response.status_code == 429:
        retry_after = response.headers.get('Retry-After', '60')
        raise APIError(f"Rate limited. Retry after {retry_after} seconds",
                      response.status_code, details)

    elif response.status_code >= 500:
        raise APIError(f"Server error: {message}", response.status_code, details)

    elif response.status_code >= 400:
        raise APIError(f"Client error: {message}", response.status_code, details)

    raise APIError(f"Unexpected error: {message}", response.status_code, details)

def api_call_with_retry(url: str, method: str = 'GET', max_retries: int = 3, **kwargs) -> Dict[str, Any]:
    """Make API call with automatic retry logic"""

    for attempt in range(1, max_retries + 1):
        try:
            response = requests.request(method, url, **kwargs)
            return handle_api_response(response)

        except APIError as e:
            if e.status_code == 429:
                retry_after = int(e.details.get('retryAfter', 60))
                time.sleep(retry_after)
                continue

            elif e.status_code >= 500 and attempt < max_retries:
                delay = 2 ** attempt  # Exponential backoff
                time.sleep(delay)
                continue

            raise

    raise APIError(f"Max retries ({max_retries}) exceeded")

Next Steps

Now that you understand response formats, explore specific API sections like Actions, Blocks, or Datasets to see these patterns in action.

An error has occurred. This application may no longer respond until reloaded. Reload ??