> For the complete documentation index, see [llms.txt](https://mobile-calendar.gitbook.io/v1/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mobile-calendar.gitbook.io/v1/overview/error-reference.md).

# Error reference

This document provides a comprehensive guide to all error responses in the mobile-calendar REST API. All errors follow the [RFC 7807 Problem Details](https://tools.ietf.org/html/rfc7807) standard and return `application/problem+json` content type.

## Overview

Every error response includes:

* **Standard HTTP status code** - Standard REST API status codes
* **RFC 7807 Problem Details** - Structured error information
* **RUID header** - Request Unique Identifier for tracing
* **Type URL** - Link to this documentation section

### Error Response Structure

```json
{
  "type": "https://mobile-calendar.gitbook.com/v1/overview/error-reference#error-slug",
  "title": "Error Title",
  "status": 400,
  "detail": "Detailed error message",
  "instance": "/api/v1/resource",
  "ruid": "550e8400-e29b-41d4-a716-446655440000"
}
```

***

## Error Types

### #bad-request

**HTTP Status:** `400 Bad Request`

**When it occurs:**

* Malformed request syntax
* Invalid request parameters
* Missing required query parameters
* Invalid data format in request body
* Type mismatch in parameters

**Common scenarios:**

* Missing required query parameter (e.g., `roomId` or `typeId`)
* Invalid enum value
* Malformed JSON in request body
* Invalid date format
* Numeric value expected but string provided

**Example Response:**

```json
{
  "type": "https://mobile-calendar.gitbook.com/v1/overview/troubleshooting#bad-request",
  "title": "Bad Request",
  "status": 400,
  "detail": "RoomId or typeId is required",
  "instance": "/api/v1/availability",
  "ruid": "7f3e9c81-5b2a-4d7e-9f1a-8c6d5e4f3a2b"
}
```

How to fix:

{% stepper %}
{% step %}

### Check the detail field

Inspect the `detail` field for specific information about what's wrong.
{% endstep %}

{% step %}

### Verify required parameters

Ensure all required parameters are present.
{% endstep %}

{% step %}

### Match parameter types

Ensure parameter types match API specification.
{% endstep %}

{% step %}

### Validate date formats

Validate date formats (ISO 8601: `YYYY-MM-DD`).
{% endstep %}

{% step %}

### Content-Type header

Check Content-Type header is set correctly (`application/json`).
{% endstep %}
{% endstepper %}

**Related endpoints:**

* `GET /api/v1/availability` - When both roomId and typeId are missing

***

### #unauthorized

**HTTP Status:** `401 Unauthorized`

**When it occurs:**

* Missing authentication credentials
* Invalid API key
* Expired authentication token
* Invalid signature for webhooks
* Missing Authorization header

**Common scenarios:**

* API key not provided in request headers
* JWT token expired
* Incorrect authentication scheme
* Invalid webhook signature from payment gateway

**Example Response:**

```json
{
  "type": "https://mobile-calendar.gitbook.com/v1/overview/troubleshooting#unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid signature",
  "instance": "/api/v1/webhook/stripe",
  "ruid": "8a4f1c92-6d3b-5e8f-0g2b-9d7e6f5g4h3c"
}
```

How to fix:

{% stepper %}
{% step %}

### Ensure Authorization header is present

Use: `Authorization: Bearer <token>`.
{% endstep %}

{% step %}

### Verify API key

Confirm API key is valid and not expired.
{% endstep %}

{% step %}

### Check token expiration

Verify authentication token hasn't expired.
{% endstep %}

{% step %}

### Webhook signature

For webhooks: verify signature calculation matches provider's specification.
{% endstep %}

{% step %}

### Regenerate credentials

Regenerate API credentials if needed.
{% endstep %}

{% step %}

### Sync system time

Check system time is synchronized (for token expiration).
{% endstep %}
{% endstepper %}

**Related endpoints:**

* All authenticated endpoints
* `/api/v1/webhook/*` - Webhook signature verification

***

### #forbidden

**HTTP Status:** `403 Forbidden`

**When it occurs:**

* Authenticated but lacking permissions
* Attempting to access another user's resources
* Feature not available in current subscription plan
* Account suspended or locked
* IP address blocked

**Common scenarios:**

* Trying to modify resources belonging to another user
* Premium feature accessed on free plan
* Employee account without sufficient permissions
* Account in trial period accessing restricted features

**Example Response:**

```json
{
  "type": "https://mobile-calendar.gitbook.com/v1/overview/troubleshooting#forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "Premium subscription required to access this feature",
  "instance": "/api/v1/rooms/123",
  "ruid": "9b5g2d03-7e4c-6f9g-1h3c-0e8f7g6h5i4d"
}
```

How to fix:

{% stepper %}
{% step %}

### Verify permissions

Confirm you have permission to access this resource.
{% endstep %}

{% step %}

### Check subscription plan

Ensure subscription plan includes this feature.
{% endstep %}

{% step %}

### Access own resources

Ensure you're accessing your own user's resources.
{% endstep %}

{% step %}

### Contact support

Contact support if account appears locked.
{% endstep %}

{% step %}

### Verify employee permissions

If using sub-account, verify employee permissions.
{% endstep %}

{% step %}

### Upgrade plan if needed

Upgrade subscription plan if necessary.
{% endstep %}
{% endstepper %}

**Related endpoints:**

* All endpoints with resource ownership checks
* Premium feature endpoints

***

### #not-found

**HTTP Status:** `404 Not Found`

**When it occurs:**

* Resource doesn't exist
* Invalid resource ID
* Resource was deleted
* Wrong endpoint URL
* Resource belongs to different user

**Common scenarios:**

* Reservation ID doesn't exist
* Room not found
* Client not found
* Rate or pricing model not found
* Room type not found
* Location not found
* Invoice not found

**Example Response:**

```json
{
  "type": "https://mobile-calendar.gitbook.com/v1/overview/troubleshooting#not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "Reservation not found",
  "instance": "/api/v1/reservations/12345",
  "ruid": "0c6h3e14-8f5d-7g0h-2i4d-1f9g8h7i6j5e"
}
```

How to fix:

{% stepper %}
{% step %}

### Verify resource ID

Confirm the resource ID is correct.
{% endstep %}

{% step %}

### Check deletion

Check the resource wasn't deleted.
{% endstep %}

{% step %}

### Correct account

Ensure you're querying the correct user account.
{% endstep %}

{% step %}

### Verify endpoint URL

Confirm the endpoint URL is correct.
{% endstep %}

{% step %}

### Check related resources

Ensure related resources exist (e.g., client exists before creating reservation).
{% endstep %}

{% step %}

### Use list endpoints

Use list endpoints to find valid IDs.
{% endstep %}
{% endstepper %}

**Related endpoints:**

* `GET /api/v1/reservations/{id}` - Reservation not found
* `GET /api/v1/rooms/{id}` - Room not found
* `GET /api/v1/clients/{id}` - Client not found
* `GET /api/v1/invoices/{id}` - Invoice not found
* `GET /api/v1/pricing/*` - Rate, room, or type not found

***

### #conflict

**HTTP Status:** `409 Conflict`

**When it occurs:**

* Resource state conflict
* Business rule violation
* Concurrent modification
* Overlapping reservations
* Resource dependencies exist

**Common scenarios:**

* Room already occupied for requested dates
* Reservation conflicts with another booking
* Cannot delete resource with active dependencies
* Client has active reservations and cannot be deleted
* Room connected to channel manager cannot be deleted
* Room connected to iCalendar sync cannot be deleted

**Example Response:**

```json
{
  "type": "https://mobile-calendar.gitbook.com/v1/overview/troubleshooting#conflict",
  "title": "Conflict",
  "status": 409,
  "detail": "Room occupied",
  "instance": "/api/v1/reservations",
  "ruid": "1d7i4f25-9g6e-8h1i-3j5e-2g0h9i8j7k6f",
  "conflicts": [
    {
      "roomId": 42,
      "arrival": "2025-11-26",
      "deaprture": "2025-11-28",
      "reservationId": 789
    }
  ]
}
```

**Extended fields:**

* `conflicts` - Array of conflicting resources with details

How to fix:

{% stepper %}
{% step %}

### Inspect conflicts field

Check the `conflicts` field for specific conflict details.
{% endstep %}

{% step %}

### Choose alternative dates or room

For room conflicts: choose different dates or a different room.
{% endstep %}

{% step %}

### Remove dependencies

For deletion conflicts: remove dependencies first (e.g., cancel reservations before deleting client).
{% endstep %}

{% step %}

### Disconnect integrations

For channel manager conflicts: disconnect integration before deleting room.
{% endstep %}

{% step %}

### Remove iCal sync

For iCalendar conflicts: remove sync connection before modification.
{% endstep %}

{% step %}

### Use optimistic locking

Implement optimistic locking in your client application.
{% endstep %}
{% endstepper %}

**Related endpoints:**

* `POST /api/v1/reservations` - Room occupation conflicts
* `PUT /api/v1/reservations/{id}` - Date change causing conflicts
* `DELETE /api/v1/clients/{id}` - Client with active reservations
* `DELETE /api/v1/rooms/{id}` - Room with channel manager or iCal connections

***

### #validation

**HTTP Status:** `422 Unprocessable Entity`

**When it occurs:**

* Request is syntactically correct but semantically invalid
* Field validation failed
* Business logic validation failed
* Required fields missing
* Invalid field format
* Constraint violation

**Common scenarios:**

* Email format invalid
* Required field is null or empty
* Value out of allowed range
* Invalid enum value
* Date in the past when future date required
* Field length exceeds maximum
* Related object validation failed (nested errors)
* Invalid state transition

**Example Response:**

```json
{
  "type": "https://mobile-calendar.gitbook.com/v1/overview/troubleshooting#validation",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "Validation failed",
  "instance": "/api/v1/rooms",
  "ruid": "2e8j5g36-0h7f-9i2j-4k6f-3h1i0j9k8l7g",
  "errors": {
    "persons": "persons cannot be less than maxAdults",
    "maxChildren": "maxChildren must be less than maxAdults",
    "email": "Invalid email format"
  }
}
```

**Extended fields:**

* `errors` - Object with field names as keys and error messages as values
* For nested validation: `"client": { "email": "Invalid format", "phone": "Required" }`

How to fix:

{% stepper %}
{% step %}

### Inspect errors object

Check the `errors` object for field-specific validation failures.
{% endstep %}

{% step %}

### Ensure required fields

Ensure all required fields are present.
{% endstep %}

{% step %}

### Verify field formats

Verify field formats match specification (email, phone, date, etc.).
{% endstep %}

{% step %}

### Check value constraints

Check value constraints (min/max length, numeric ranges).
{% endstep %}

{% step %}

### Validate business rules

Validate business rules (e.g., persons >= maxAdults).
{% endstep %}

{% step %}

### Fix nested errors

For nested errors: fix the nested object's validation issues.
{% endstep %}

{% step %}

### Review API documentation

Review API documentation for field requirements.
{% endstep %}
{% endstepper %}

Common validation rules:

* `email` - Must be valid email format
* `phone` - Must be valid phone number format
* `taxId` / `nip` - Must be valid tax identification format
* `dates` - Must be ISO 8601 format (YYYY-MM-DD)
* `persons` - Must be >= maxAdults
* `maxChildren` - Must be < maxAdults
* `paymentStatus` - Cannot modify reservation waiting for payment

**Related endpoints:**

* `POST /api/v1/reservations` - Reservation field validation
* `POST /api/v1/rooms` - Room field validation
* `POST /api/v1/clients` - Client field validation
* `POST /api/v1/invoices` - Invoice field validation
* `PUT /api/v1/*` - Update operations with validation

***

### #rate-limit

**HTTP Status:** `429 Too Many Requests`

**When it occurs:**

* API rate limit exceeded
* Too many requests from single IP
* Quota exhausted for time period
* DDoS protection triggered

**Common scenarios:**

* Making too many API calls per minute/hour
* Burst of requests exceeding rate limit
* Multiple concurrent requests from same client
* Automated scripts without proper rate limiting

**Example Response:**

```json
{
  "type": "https://mobile-calendar.gitbook.com/v1/overview/troubleshooting#rate-limit",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded. Maximum 100 requests per minute.",
  "instance": "/api/v1/reservations",
  "ruid": "3f9k6h47-1i8g-0j3k-5l7g-4i2j1k0l9m8h",
  "retryAfter": 45
}
```

**Extended fields:**

* `retryAfter` - Number of seconds to wait before retrying

Response headers:

* `Retry-After` - Seconds until rate limit resets
* `X-RateLimit-Limit` - Total requests allowed in period
* `X-RateLimit-Remaining` - Requests remaining in current period
* `X-RateLimit-Reset` - Unix timestamp when limit resets

How to fix:

{% stepper %}
{% step %}

### Implement exponential backoff

Implement exponential backoff in your client.
{% endstep %}

{% step %}

### Respect Retry-After

Respect the `Retry-After` header value.
{% endstep %}

{% step %}

### Add delays

Add delay between requests.
{% endstep %}

{% step %}

### Cache responses

Cache responses when possible.
{% endstep %}

{% step %}

### Use bulk operations

Use bulk operations instead of individual requests.
{% endstep %}

{% step %}

### Monitor and throttle

Monitor rate limit headers and throttle proactively.
{% endstep %}

{% step %}

### Upgrade plan

Consider upgrading plan for higher rate limits.
{% endstep %}

{% step %}

### Request queuing

Implement request queuing in your application.
{% endstep %}
{% endstepper %}

Rate limits by plan:

* Premium: 60 requests/minute

***

### #internal

**HTTP Status:** `500 Internal Server Error`

**When it occurs:**

* Unexpected server error
* Database connection failure
* Unhandled exception
* External service failure
* Data corruption
* Critical system error

**Common scenarios:**

* Database query failure
* Failed to create resource in database
* External payment gateway error
* Email service unavailable
* File system error
* Memory exhaustion

**Example Response:**

```json
{
  "type": "https://mobile-calendar.gitbook.com/v1/overview/troubleshooting#internal",
  "title": "Internal Server Error",
  "status": 500,
  "detail": "Failed to create invoice",
  "instance": "/api/v1/invoices",
  "ruid": "4g0l7i58-2j9h-1k4l-6m8h-5j3k2l1m0n9i"
}
```

How to fix:

{% stepper %}
{% step %}

### Save the RUID

Save the RUID — it's critical for support investigation.
{% endstep %}

{% step %}

### Retry with backoff

Retry the request after a brief delay (use exponential backoff).
{% endstep %}

{% step %}

### Check API status

Check API status page: <https://status.mobile-calendar.com>
{% endstep %}

{% step %}

### Contact support

Contact support with RUID if error persists.
{% endstep %}

{% step %}

### Verify payload

Verify your payload doesn't contain corrupted data.
{% endstep %}

{% step %}

### Reproduce and review

Check if the issue is reproducible and review recent integration changes.
{% endstep %}
{% endstepper %}

What we do:

* Every 500 error is automatically logged
* Development team is notified for investigation
* RUID allows us to trace the exact request
* We monitor 500 error rates in real-time

Support escalation: When contacting support, provide:

{% stepper %}
{% step %}

### RUID

Provide the `ruid` from the error response.
{% endstep %}

{% step %}

### Timestamp

Provide timestamp of the error.
{% endstep %}

{% step %}

### Request payload

Provide request payload (if safe to share).
{% endstep %}

{% step %}

### Steps to reproduce

Provide steps to reproduce.
{% endstep %}

{% step %}

### Frequency

Provide frequency of occurrence.
{% endstep %}
{% endstepper %}

***

## Error Handling Best Practices

### Always Check RUID

Every response includes a `ruid` (Request Unique Identifier) in both the header and response body. Save this for:

* Debugging issues
* Contacting support
* Correlating logs
* Tracking request flow

```javascript
// Example: Extract RUID from response
const ruid = response.headers.get('RUID') || response.data.ruid;
console.error(`Error occurred: ${ruid}`);
```

### Parse Problem Details

Always parse the RFC 7807 Problem Details format:

```javascript
// Example: Proper error handling
try {
  const response = await fetch('/api/v1/reservations', {
    method: 'POST',
    body: JSON.stringify(data)
  });
  
  if (!response.ok) {
    const problem = await response.json();
    
    // Access structured error information
    console.error('Type:', problem.type);
    console.error('Title:', problem.title);
    console.error('Status:', problem.status);
    console.error('Detail:', problem.detail);
    console.error('RUID:', problem.ruid);
    
    // Handle specific error types
    if (problem.status === 422 && problem.errors) {
      // Validation errors
      Object.entries(problem.errors).forEach(([field, error]) => {
        showFieldError(field, error);
      });
    } else if (problem.status === 409 && problem.conflicts) {
      // Conflict errors
      showConflicts(problem.conflicts);
    }
  }
} catch (error) {
  console.error('Network error:', error);
}
```

### Implement Retry Logic

For transient errors (500, 429), implement retry with exponential backoff:

```javascript
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i);
        await sleep(retryAfter * 1000);
        continue;
      }
      
      if (response.status >= 500 && i < maxRetries - 1) {
        await sleep(Math.pow(2, i) * 1000);
        continue;
      }
      
      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await sleep(Math.pow(2, i) * 1000);
    }
  }
}
```

### Handle Validation Errors

Display validation errors next to form fields:

```javascript
function handleValidationErrors(errors) {
  // Clear previous errors
  clearAllFieldErrors();
  
  // Display field-specific errors
  Object.entries(errors).forEach(([field, message]) => {
    const fieldElement = document.querySelector(`[name="${field}"]`);
    if (fieldElement) {
      showFieldError(fieldElement, message);
    }
  });
}
```

### Monitor Error Rates

Track error responses in your application:

```javascript
// Example: Error monitoring
function trackError(problem) {
  analytics.track('API Error', {
    status: problem.status,
    type: problem.type,
    endpoint: problem.instance,
    ruid: problem.ruid,
    detail: problem.detail
  });
}
```

### User-Friendly Messages

Map technical errors to user-friendly messages:

```javascript
const userMessages = {
  400: 'Please check your input and try again.',
  401: 'Please log in to continue.',
  403: 'You don\'t have permission to perform this action.',
  404: 'The requested item could not be found.',
  409: 'This action conflicts with existing data.',
  422: 'Please correct the highlighted fields.',
  429: 'Too many requests. Please wait a moment.',
  500: 'Something went wrong. Please try again later.'
};

function showUserError(status, detail) {
  const message = userMessages[status] || 'An error occurred.';
  showNotification(message, detail);
}
```

***

## HTTP Status Code Reference

Quick reference for all status codes used in the API:

| Code | Name                  | Error Type      | Description                                    |
| ---- | --------------------- | --------------- | ---------------------------------------------- |
| 200  | OK                    | -               | Successful GET request                         |
| 201  | Created               | -               | Successful POST creating resource              |
| 204  | No Content            | -               | Successful DELETE or PUT with no response body |
| 400  | Bad Request           | `#bad-request`  | Malformed request syntax or invalid parameters |
| 401  | Unauthorized          | `#unauthorized` | Missing or invalid authentication              |
| 403  | Forbidden             | `#forbidden`    | Authenticated but lacking permissions          |
| 404  | Not Found             | `#not-found`    | Resource doesn't exist                         |
| 409  | Conflict              | `#conflict`     | Resource state conflict                        |
| 422  | Unprocessable Entity  | `#validation`   | Validation failed                              |
| 429  | Too Many Requests     | `#rate-limit`   | Rate limit exceeded                            |
| 500  | Internal Server Error | `#internal`     | Unexpected server error                        |

***

## Support and Resources

### Documentation

* API Documentation: <https://mobile-calendar.gitbook.com/v1>
* Status Page: <https://api.mobile-calendar.com/v1/health>
* Api/Logs/Webhooks/Developer Portal: <https://app.mobile-calendar.com/en/app/rest-api>

### Contact Support

* Email: <api-support@mobile-calendar.com>
* Support Portal: <https://support.mobile-calendar.com>

When reporting errors, always include:

{% stepper %}
{% step %}

### RUID

RUID from the error response.
{% endstep %}

{% step %}

### Timestamp

Timestamp when error occurred.
{% endstep %}

{% step %}

### HTTP method and endpoint

HTTP method and endpoint used.
{% endstep %}

{% step %}

### Expected vs actual behavior

Describe expected vs actual behavior.
{% endstep %}

{% step %}

### Steps to reproduce

Provide steps to reproduce.
{% endstep %}
{% endstepper %}

### Additional Resources

* [RFC 7807 - Problem Details](https://tools.ietf.org/html/rfc7807)
* [Authentication Guide](https://mobile-calendar.gitbook.com/v1/authentication)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://mobile-calendar.gitbook.io/v1/overview/error-reference.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
