BizCARE MyInvois
API Reference

Error Handling

Understanding API errors and how to handle them

Error Handling

The BizCARE MyInvois API uses conventional HTTP response codes to indicate the success or failure of an API request. This guide explains the error codes, their meanings, and how to handle them effectively.

HTTP Status Codes

Success Codes

CodeStatusDescription
200OKRequest succeeded
201CreatedResource created successfully
202AcceptedRequest accepted for processing
204No ContentRequest succeeded, no content returned

Client Error Codes

CodeStatusDescription
400Bad RequestInvalid request format or parameters
401UnauthorizedAuthentication required or invalid
403ForbiddenAccess denied
404Not FoundResource not found
406Not AcceptableRequest format not acceptable
409ConflictResource conflict (e.g., duplicate invoice code)
422Unprocessable EntityValidation errors

Server Error Codes

CodeStatusDescription
500Internal Server ErrorServer encountered an error
502Bad GatewayInvalid response from upstream server
503Service UnavailableService temporarily unavailable
504Gateway TimeoutRequest timeout

Error Response Format

All error responses follow a consistent JSON format:

{
  "error": "error_type",
  "message": "Human-readable error message",
  "details": {
    "field": "Additional error details"
  }
}

Error Response Fields

FieldTypeDescription
errorstringError type identifier
messagestringHuman-readable error description
detailsobjectAdditional error information (optional)

Common Error Types

Authentication Errors

401 Unauthorized - Missing Authentication

{
  "error": "Unauthorized",
  "message": "Authentication required"
}

Cause: No authentication header provided Solution: Include X-API-Key or Authorization header

401 Unauthorized - Invalid Credentials

{
  "error": "Unauthorized",
  "message": "Invalid API key"
}

Cause: Invalid or expired API key/token Solution: Check your API key or refresh your token

403 Forbidden - Access Denied

{
  "error": "Access token is missing or invalid",
  "message": "You don't have permission to access this resource"
}

Cause: Valid authentication but insufficient permissions Solution: Check your account permissions or contact support


Validation Errors

422 Unprocessable Entity - Field Validation

{
  "error": "validation_error",
  "message": "The given data was invalid",
  "details": {
    "invoice_code": ["The invoice code field is required"],
    "buyer.name": ["The buyer name field is required"],
    "line_items.0.quantity": ["The quantity must be greater than 0"]
  }
}

Cause: Required fields missing or invalid data format Solution: Check the details object for specific field errors

400 Bad Request - Invalid Format

{
  "error": "Bad Request",
  "message": "Invalid JSON format"
}

Cause: Malformed JSON in request body Solution: Validate your JSON syntax


Business Logic Errors

409 Conflict - Duplicate Invoice Code

{
  "success": false,
  "message": "Invoice code already exists"
}

Cause: Attempting to create an invoice with an existing invoice code Solution: Use the validation endpoint to check uniqueness first

403 Forbidden - Invoice Cannot Be Modified

{
  "success": false,
  "message": "Invoice cannot be updated"
}

Cause: Trying to modify an invoice that has already been submitted Solution: Only draft orders can be modified

403 Forbidden - Invoice Cannot Be Deleted

{
  "success": false,
  "message": "Invoice cannot be deleted"
}

Cause: Trying to delete an invoice that has been submitted Solution: Only draft orders can be deleted


Resource Errors

404 Not Found - Invoice

{
  "error": "Invoice not found",
  "message": "The requested invoice does not exist"
}

Cause: Invoice ID doesn't exist or doesn't belong to your company Solution: Verify the invoice ID and your access permissions

404 Not Found - Company

{
  "message": "Company not found"
}

Cause: Company not found or not accessible Solution: Complete company setup or check permissions


External Service Errors

400 Bad Request - TIN Validation

{
  "error": "invalid_tin",
  "error_description": "The provided TIN is not valid",
  "error_uri": "https://docs.example.com/validation/tin"
}

Cause: Invalid TIN format or TIN not found in government database Solution: Verify TIN format and check with Malaysian tax authorities

500 Internal Server Error - MyInvois Integration

{
  "error": "Internal server error",
  "message": "Failed to connect to MyInvois service"
}

Cause: MyInvois service unavailable or integration error Solution: Retry the request or contact support if the issue persists


Error Handling Best Practices

1. Always Check Status Codes

const response = await fetch('/api/orders', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your-api-key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(orderData)
});

if (!response.ok) {
  const error = await response.json();
  console.error('API Error:', error);
  // Handle error based on status code
  switch (response.status) {
    case 401:
      // Handle authentication error
      break;
    case 422:
      // Handle validation errors
      break;
    case 409:
      // Handle conflict (duplicate invoice code)
      break;
    default:
      // Handle other errors
  }
}

2. Handle Validation Errors

if (response.status === 422) {
  const error = await response.json();
  if (error.details) {
    // Display field-specific errors
    Object.keys(error.details).forEach(field => {
      console.error(`${field}: ${error.details[field].join(', ')}`);
    });
  }
}

3. Implement Retry Logic

async function apiRequest(url, options, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      
      if (response.ok) {
        return response;
      }
      
      // Don't retry client errors (4xx)
      if (response.status >= 400 && response.status < 500) {
        throw new Error(`Client error: ${response.status}`);
      }
      
      // Retry server errors (5xx)
      if (attempt === maxRetries) {
        throw new Error(`Server error after ${maxRetries} attempts`);
      }
      
      // Wait before retrying
      await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
      
    } catch (error) {
      if (attempt === maxRetries) {
        throw error;
      }
    }
  }
}

4. Log Errors for Debugging

function logError(error, context) {
  console.error('API Error:', {
    timestamp: new Date().toISOString(),
    context,
    error: {
      status: error.status,
      message: error.message,
      details: error.details
    }
  });
}

Rate Limiting

When you exceed rate limits, you'll receive a 429 Too Many Requests response:

{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Please try again later.",
  "retry_after": 3600
}

Rate Limit Headers

All responses include rate limiting information:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200

Handling Rate Limits

if (response.status === 429) {
  const retryAfter = response.headers.get('Retry-After');
  console.log(`Rate limited. Retry after ${retryAfter} seconds`);
  
  // Wait and retry
  setTimeout(() => {
    // Retry the request
  }, retryAfter * 1000);
}

Troubleshooting Guide

Common Issues and Solutions

IssuePossible CausesSolutions
401 UnauthorizedInvalid API key, expired tokenCheck API key, refresh token
422 Validation ErrorMissing required fields, invalid dataReview field requirements, validate data
409 ConflictDuplicate invoice codeUse unique invoice codes, check validation endpoint
500 Server ErrorService unavailable, integration issuesRetry request, contact support

Debug Checklist

  1. Check API Key: Ensure your API key is valid and properly formatted
  2. Verify Request Format: Confirm JSON syntax and required headers
  3. Validate Data: Check all required fields and data formats
  4. Check Permissions: Ensure your account has necessary permissions
  5. Review Rate Limits: Check if you've exceeded rate limits
  6. Test with Minimal Data: Try with the simplest possible request first

Error Logging: Always log errors with sufficient context for debugging, but avoid logging sensitive information like API keys.

Retry Strategy: Implement exponential backoff for retries to avoid overwhelming the server.