Skip to main content
Rinne uses standard HTTP status codes and provides detailed error responses to help you debug issues quickly.

Error response format

All errors follow a consistent structure:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation error",
    "status": 400,
    "path": "/v1/transactions",
    "timestamp": "2025-01-21T10:30:00.000Z",
    "requestId": "req_123456789",
    "details": {
      "issues": [
        {
          "field": "amount",
          "type": "REQUIRED",
          "message": "Field 'amount' is required"
        }
      ]
    }
  }
}

Error fields

  • code: Machine-readable error code
  • message: Human-readable error message
  • status: HTTP status code
  • path: API endpoint that generated the error
  • timestamp: When the error occurred
  • requestId: Unique request identifier for support
  • details: Additional error-specific information

HTTP status codes

CodeDescriptionCommon causes
400Bad RequestInvalid input, validation errors
401UnauthorizedMissing or invalid API key
403ForbiddenInsufficient permissions
404Not FoundResource doesn’t exist
409ConflictDuplicate resource, invalid state
500Internal Server ErrorServer-side error
502Bad GatewayProvider integration error

Common error codes

VALIDATION_ERROR (400)

Input validation failed. Check the details.issues array for specific field errors.
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation error",
    "details": {
      "issues": [
        {
          "field": "amount",
          "type": "INVALID_TYPE",
          "message": "Expected number, received string",
          "value": "invalid"
        }
      ]
    }
  }
}
Solution: Fix the invalid fields and retry the request.

AUTHENTICATION_ERROR (401)

API key is missing or invalid.
{
  "error": {
    "code": "AUTHENTICATION_ERROR",
    "message": "Invalid or missing API key",
    "details": {
      "reason": "API key not found"
    }
  }
}
Solution: Verify your API key is correct and included in the x-api-key header.

AUTHORIZATION_ERROR (403)

You don’t have permission to access the resource.
{
  "error": {
    "code": "AUTHORIZATION_ERROR",
    "message": "You need 'transaction.create' permission to access this resource"
  }
}
Solution: Check your user roles and permissions, or use an API key with appropriate access.

RESOURCE_NOT_FOUND (404)

The requested resource doesn’t exist.
{
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "Transaction with ID 'tx_123' not found"
  }
}
Solution: Verify the resource ID is correct and belongs to your company.

CONFLICT_ERROR (409)

Resource already exists or operation conflicts with current state.
{
  "error": {
    "code": "CONFLICT_ERROR",
    "message": "Company with this document_number already exists",
    "details": {
      "field": "document_number",
      "value": "16525269000121"
    }
  }
}
Solution: Check for existing resources or verify the resource state allows the operation.

INTEGRATION_ERROR (502)

Provider integration failed.
{
  "error": {
    "code": "INTEGRATION_ERROR",
    "message": "Integration error with provider CELCOIN",
    "status": 502
  }
}
Solution: Retry the request. If the error persists, contact support with the requestId.

Handling validation errors

Validation errors include detailed information about each invalid field:
try {
  const response = await createTransaction(data);
} catch (error) {
  if (error.status === 400 && error.code === 'VALIDATION_ERROR') {
    error.details.issues.forEach(issue => {
      console.log(`Field ${issue.field}: ${issue.message}`);
      // Display error to user
    });
  }
}

Idempotency

Use the request_id field to safely retry requests:
# First attempt - network error
POST /v1/transactions
{ "request_id": "order-123", ... }
# Network timeout

# Retry with same request_id
POST /v1/transactions
{ "request_id": "order-123", ... }
# Returns existing transaction if first request succeeded
This prevents duplicate transactions when retrying failed requests.

Rate limiting

Rinne implements rate limiting to ensure platform stability. If you exceed rate limits, you’ll receive a 429 status code:
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests",
    "status": 429,
    "details": {
      "retry_after": 60
    }
  }
}
Implement exponential backoff when retrying:
async function retryWithBackoff(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status === 429 && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}

Logging and debugging

Request IDs

Every response includes a requestId that you can use when contacting support:
{
  "error": {
    "requestId": "req_123456789"
  }
}
Save request IDs for failed requests to help support diagnose issues.

Error monitoring

Implement error monitoring to track API errors:
app.use((error, req, res, next) => {
  // Log to monitoring service
  logger.error('Rinne API error', {
    code: error.code,
    status: error.status,
    requestId: error.requestId,
    path: req.path
  });
  
  // Send to error tracking (Sentry, etc.)
  Sentry.captureException(error);
});

Next steps