Skip to content

Error Handling

DialogueDB uses standardized error responses to help you handle failures gracefully and build robust applications.

Error Response Format

All error responses follow a consistent structure:

json
{
  "error": {
    "code": "DIALOGUE_NOT_FOUND",
    "message": "Dialogue 'dlg_abc123' not found",
    "type": "not_found",
    "details": [
      {
        "field": "id",
        "code": "NOT_FOUND",
        "message": "Resource does not exist"
      }
    ],
    "requestId": "req_xyz789",
    "timestamp": "2025-11-06T21:34:21.117Z"
  }
}

Error Object Fields

FieldTypeDescription
codestringMachine-readable error code (e.g., DIALOGUE_NOT_FOUND)
messagestringHuman-readable error description
typestringError category: validation_error, not_found, conflict, rate_limit, server
detailsarrayOptional field-level validation errors
requestIdstringUnique request identifier for debugging
timestampstringISO 8601 timestamp when the error occurred

HTTP Status Codes

DialogueDB uses standard HTTP status codes to indicate the type of error:

StatusMeaningWhen Used
400Bad RequestValidation errors, missing required fields, invalid input
401UnauthorizedMissing or invalid authentication token
404Not FoundResource (dialogue, message, project) does not exist
409ConflictResource conflict (e.g., dialogue immutability violation)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Error Types

Validation Errors (400)

Returned when request data is invalid or missing required fields.

Example:

json
{
  "error": {
    "code": "MISSING_PARAMETER",
    "message": "Missing required parameter: id",
    "type": "validation_error",
    "details": [
      {
        "field": "id",
        "code": "REQUIRED",
        "message": "Dialogue ID is required"
      }
    ],
    "requestId": "req_123",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Common validation error codes:

  • MISSING_PARAMETER - Required parameter not provided
  • INVALID_PARAMETER - Parameter format is invalid
  • MESSAGE_CONTENT_EMPTY - Message content cannot be empty
  • MESSAGE_TOO_LARGE - Message exceeds size limit
  • TOO_MANY_MESSAGES - Exceeds message limit on creation
  • INVALID_MESSAGE_ARRAY - Messages must be an array
  • INVALID_ACTION - Unsupported action specified

Not Found Errors (404)

Returned when a requested resource does not exist.

Example:

json
{
  "error": {
    "code": "DIALOGUE_NOT_FOUND",
    "message": "Dialogue 'dlg_abc123' not found",
    "type": "not_found",
    "requestId": "req_456",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Common not found error codes:

  • DIALOGUE_NOT_FOUND - Dialogue does not exist
  • MESSAGE_NOT_FOUND - Message does not exist
  • PROJECT_NOT_FOUND - Project does not exist
  • PARENT_DIALOGUE_NOT_FOUND - Parent dialogue for thread not found

Conflict Errors (409)

Returned when operation conflicts with resource state.

Example:

json
{
  "error": {
    "code": "DIALOGUE_IMMUTABLE",
    "message": "Cannot delete message: dialogues are immutable in this project",
    "type": "conflict",
    "requestId": "req_789",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Common conflict error codes:

  • DIALOGUE_IMMUTABLE - Operation not allowed on immutable dialogue
  • DUPLICATE_ID - Resource with this ID already exists
  • RESOURCE_CONFLICT - Operation conflicts with resource state

Rate Limit Errors (429)

Returned when API rate limits are exceeded.

Example:

json
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Please try again later.",
    "type": "rate_limit",
    "requestId": "req_999",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Response headers:

http
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640000060
Retry-After: 60

Server Errors (500)

Returned for unexpected server-side errors.

Example:

json
{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "An internal error occurred while processing your request",
    "type": "server",
    "requestId": "req_555",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Error Code Reference

Validation Errors (400)

CodeHTTP StatusDescription
MISSING_PARAMETER400Required parameter missing from request
INVALID_PARAMETER400Parameter format or value is invalid
INVALID_INPUT400Input validation failed
VALIDATION_ERROR400General validation error
MESSAGE_CONTENT_EMPTY400Message content cannot be empty
MESSAGE_TOO_LARGE400Message exceeds maximum size (1MB uncompressed)
TOO_MANY_MESSAGES400Exceeds message limit on creation
INVALID_MESSAGE_ARRAY400Messages parameter must be an array
EMPTY_MESSAGE_ARRAY400Messages array cannot be empty
INVALID_ACTION400Unsupported action specified
SEARCH_QUERY_TOO_SHORT400Search query must be at least 3 characters

Not Found Errors (404)

CodeHTTP StatusDescription
DIALOGUE_NOT_FOUND404Dialogue with specified ID not found
MESSAGE_NOT_FOUND404Message with specified ID not found
PROJECT_NOT_FOUND404Project does not exist
PARENT_DIALOGUE_NOT_FOUND404Parent dialogue for thread not found
RESOURCE_NOT_FOUND404Generic resource not found

Conflict Errors (409)

CodeHTTP StatusDescription
DIALOGUE_IMMUTABLE409Operation not allowed on immutable dialogue
DUPLICATE_ID409Resource with this ID already exists
RESOURCE_CONFLICT409Operation conflicts with resource state

Rate Limit & Plan Limit Errors (429)

CodeHTTP StatusDescription
RATE_LIMIT_EXCEEDED429Too many requests - retry after delay
PLAN_LIMIT_EXCEEDED429Plan quota exceeded - upgrade to continue writing. Existing data remains accessible; only new writes are blocked. No overage charges.

Server Errors (500)

CodeHTTP StatusDescription
INTERNAL_ERROR500Unexpected server error
DATABASE_ERROR500Database operation failed
TRANSACTION_FAILED500Database transaction failed

Error Handling Best Practices

1. Always Check HTTP Status Codes

bash
# Check the HTTP status code in the response
STATUS=$(curl -s -o response.json -w "%{http_code}" \
  -X GET https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123 \
  -H "Authorization: Bearer DIALOGUE_DB_API_KEY")

case $STATUS in
  400)
    echo "Invalid request: $(jq -r '.error.message' response.json)"
    ;;
  404)
    echo "Resource not found: $(jq -r '.error.code' response.json)"
    ;;
  429)
    RETRY_AFTER=$(grep -i 'retry-after' headers.txt | awk '{print $2}')
    echo "Rate limited. Retry after ${RETRY_AFTER}s"
    sleep "$RETRY_AFTER"
    ;;
  500)
    echo "Server error. Request ID: $(jq -r '.error.requestId' response.json)"
    ;;
esac
typescript
const response = await fetch(url, options);

if (!response.ok) {
  const error = await response.json();

  switch (response.status) {
    case 400:
      // Validation error - fix request
      console.error('Invalid request:', error.error.message);
      break;
    case 404:
      // Not found - handle missing resource
      console.error('Resource not found:', error.error.code);
      break;
    case 429:
      // Rate limited - retry with backoff
      await sleep(parseInt(response.headers.get('Retry-After')!) * 1000);
      return retry();
    case 500:
      // Server error - retry or alert
      console.error('Server error:', error.error.requestId);
      break;
  }
}
python
import requests

response = requests.get(
    "https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123",
    headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"}
)

if not response.ok:
    error = response.json()["error"]

    if response.status_code == 400:
        # Validation error - fix request
        print(f"Invalid request: {error['message']}")
    elif response.status_code == 404:
        # Not found - handle missing resource
        print(f"Resource not found: {error['code']}")
    elif response.status_code == 429:
        # Rate limited - retry with backoff
        retry_after = int(response.headers.get("Retry-After", 1))
        time.sleep(retry_after)
        # retry...
    elif response.status_code == 500:
        # Server error - retry or alert
        print(f"Server error: {error['requestId']}")
typescript
import { DialogueDB, DialogueDBError } from 'dialogue-db';

const db = new DialogueDB({ apiKey: 'DIALOGUE_DB_API_KEY' });

try {
  const dialogue = await db.getDialogue('dlg_abc123');
} catch (error) {
  if (error instanceof DialogueDBError) {
    switch (error.statusCode) {
      case 400:
        console.error('Invalid request:', error.message);
        break;
      case 404:
        console.error('Resource not found:', error.code);
        break;
      case 429:
        // Rate limited - SDK handles retries automatically
        break;
      case 500:
        console.error('Server error:', error.requestId);
        break;
    }
  }
}

2. Use Error Codes for Logic

bash
# Attempt to get a dialogue, create if not found
RESPONSE=$(curl -s -w "\n%{http_code}" \
  -X GET https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123 \
  -H "Authorization: Bearer DIALOGUE_DB_API_KEY")

BODY=$(echo "$RESPONSE" | sed '$d')
STATUS=$(echo "$RESPONSE" | tail -1)
ERROR_CODE=$(echo "$BODY" | jq -r '.error.code // empty')

if [ "$ERROR_CODE" = "DIALOGUE_NOT_FOUND" ]; then
  # Create new dialogue
  curl -s -X POST https://api.dialoguedb.com/api/v1/dialogue \
    -H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"projectId": "proj_123"}'
elif [ "$ERROR_CODE" = "RATE_LIMIT_EXCEEDED" ]; then
  echo "Rate limited. Retrying..."
  sleep 1
fi
typescript
const response = await fetch(
  'https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123',
  { headers: { 'Authorization': 'Bearer DIALOGUE_DB_API_KEY' } }
);

if (!response.ok) {
  const { error } = await response.json();

  if (error.code === 'DIALOGUE_NOT_FOUND') {
    // Create new dialogue
    return fetch('https://api.dialoguedb.com/api/v1/dialogue', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ projectId: 'proj_123' }),
    });
  }

  if (error.code === 'RATE_LIMIT_EXCEEDED') {
    await sleep(1000);
    return retry();
  }

  throw new Error(error.message);
}
python
import requests

response = requests.get(
    "https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123",
    headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"}
)

if not response.ok:
    error = response.json()["error"]

    if error["code"] == "DIALOGUE_NOT_FOUND":
        # Create new dialogue
        response = requests.post(
            "https://api.dialoguedb.com/api/v1/dialogue",
            headers={
                "Authorization": "Bearer DIALOGUE_DB_API_KEY",
                "Content-Type": "application/json",
            },
            json={"projectId": "proj_123"},
        )
    elif error["code"] == "RATE_LIMIT_EXCEEDED":
        time.sleep(1)
        # retry...
    else:
        raise Exception(error["message"])
typescript
try {
  const dialogue = await db.getDialogue(dialogueId);
} catch (error) {
  if (error.code === 'DIALOGUE_NOT_FOUND') {
    // Create new dialogue
    return db.createDialogue({ projectId: 'proj_123' });
  }

  if (error.code === 'RATE_LIMIT_EXCEEDED') {
    // Wait and retry
    await sleep(1000);
    return retry();
  }

  // Unknown error - propagate
  throw error;
}

3. Handle Validation Errors with Details

bash
# Send an invalid request and parse validation details
RESPONSE=$(curl -s -X POST https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123/messages \
  -H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"messages": [{"role": "user", "content": ""}]}')

ERROR_TYPE=$(echo "$RESPONSE" | jq -r '.error.type')

if [ "$ERROR_TYPE" = "validation_error" ]; then
  echo "$RESPONSE" | jq -r '.error.details[]? | "\(.field): \(.message)"'
fi
typescript
const response = await fetch(
  'https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123/messages',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ messages: [{ role: 'user', content: '' }] }),
  }
);

if (!response.ok) {
  const { error } = await response.json();

  if (error.type === 'validation_error' && error.details) {
    // Show field-level errors to user
    error.details.forEach((detail: { field: string; message: string }) => {
      console.error(`${detail.field}: ${detail.message}`);
    });
  }
}
python
import requests

response = requests.post(
    "https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123/messages",
    headers={
        "Authorization": "Bearer DIALOGUE_DB_API_KEY",
        "Content-Type": "application/json",
    },
    json={"messages": [{"role": "user", "content": ""}]},
)

if not response.ok:
    error = response.json()["error"]

    if error["type"] == "validation_error" and "details" in error:
        # Show field-level errors to user
        for detail in error["details"]:
            print(f"{detail['field']}: {detail['message']}")
typescript
try {
  await dialogue.saveMessage(message);
} catch (error) {
  if (error.type === 'validation_error' && error.details) {
    // Show field-level errors to user
    error.details.forEach((detail: { field: string; message: string }) => {
      console.error(`${detail.field}: ${detail.message}`);
    });
  }
}

4. Log Request IDs for Support

bash
# Capture and log the request ID from error responses
RESPONSE=$(curl -s -X DELETE https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123 \
  -H "Authorization: Bearer DIALOGUE_DB_API_KEY")

ERROR_CODE=$(echo "$RESPONSE" | jq -r '.error.code // empty')

if [ -n "$ERROR_CODE" ]; then
  REQUEST_ID=$(echo "$RESPONSE" | jq -r '.error.requestId')
  MESSAGE=$(echo "$RESPONSE" | jq -r '.error.message')
  echo "Operation failed"
  echo "  Request ID: $REQUEST_ID"
  echo "  Code: $ERROR_CODE"
  echo "  Message: $MESSAGE"
  echo "Contact support with Request ID: $REQUEST_ID"
fi
typescript
const response = await fetch(
  'https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123',
  {
    method: 'DELETE',
    headers: { 'Authorization': 'Bearer DIALOGUE_DB_API_KEY' },
  }
);

if (!response.ok) {
  const { error } = await response.json();

  // Always log requestId for debugging
  console.error('Operation failed', {
    requestId: error.requestId,
    code: error.code,
    message: error.message,
  });

  // Show friendly message to user, provide requestId for support
  alert(`Operation failed. Please contact support with ID: ${error.requestId}`);
}
python
import requests

response = requests.delete(
    "https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123",
    headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"}
)

if not response.ok:
    error = response.json()["error"]

    # Always log requestId for debugging
    print(f"Operation failed:")
    print(f"  Request ID: {error['requestId']}")
    print(f"  Code: {error['code']}")
    print(f"  Message: {error['message']}")
    print(f"Contact support with Request ID: {error['requestId']}")
typescript
try {
  await api.dialogue.remove({ id: dialogueId });
} catch (error) {
  // Always log requestId for debugging
  console.error('Operation failed', {
    requestId: error.requestId,
    code: error.code,
    message: error.message,
  });

  // Show friendly message to user, provide requestId for support
  alert(`Operation failed. Please contact support with ID: ${error.requestId}`);
}

5. Implement Retry Logic for Transient Errors

bash
# Retry with exponential backoff
MAX_RETRIES=3
ATTEMPT=0

while [ $ATTEMPT -lt $MAX_RETRIES ]; do
  RESPONSE=$(curl -s -o response.json -w "%{http_code}" \
    -X GET https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123 \
    -H "Authorization: Bearer DIALOGUE_DB_API_KEY")

  if [ "$RESPONSE" -lt 400 ]; then
    cat response.json
    break
  fi

  ERROR_CODE=$(jq -r '.error.code // empty' response.json)

  # Only retry on rate limits and server errors
  if [ "$ERROR_CODE" = "RATE_LIMIT_EXCEEDED" ] || [ "$RESPONSE" -ge 500 ]; then
    DELAY=$(( 1 << ATTEMPT ))  # 1, 2, 4 seconds
    [ $DELAY -gt 10 ] && DELAY=10
    echo "Retrying in ${DELAY}s (attempt $((ATTEMPT + 1))/$MAX_RETRIES)..."
    sleep $DELAY
    ATTEMPT=$((ATTEMPT + 1))
  else
    # Don't retry validation or not found errors
    cat response.json
    break
  fi
done
typescript
async function withRetry<T>(
  fn: () => Promise<Response>,
  maxRetries = 3
): Promise<Response> {
  let lastError: Error | undefined;

  for (let i = 0; i < maxRetries; i++) {
    const response = await fn();

    if (response.ok) {
      return response;
    }

    const { error } = await response.json();
    lastError = new Error(error.message);

    // Only retry on rate limits and server errors
    if (error.code === 'RATE_LIMIT_EXCEEDED' || error.type === 'server') {
      const delay = Math.min(1000 * Math.pow(2, i), 10000);
      await new Promise((resolve) => setTimeout(resolve, delay));
      continue;
    }

    // Don't retry validation or not found errors
    throw lastError;
  }

  throw lastError;
}

// Usage
const response = await withRetry(() =>
  fetch('https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123', {
    headers: { 'Authorization': 'Bearer DIALOGUE_DB_API_KEY' },
  })
);
python
import time
import requests

def with_retry(fn, max_retries=3):
    last_error = None

    for i in range(max_retries):
        response = fn()

        if response.ok:
            return response

        error = response.json()["error"]
        last_error = Exception(error["message"])

        # Only retry on rate limits and server errors
        if error["code"] == "RATE_LIMIT_EXCEEDED" or error["type"] == "server":
            delay = min(2 ** i, 10)
            time.sleep(delay)
            continue

        # Don't retry validation or not found errors
        raise last_error

    raise last_error

# Usage
response = with_retry(lambda: requests.get(
    "https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123",
    headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
))
typescript
async function withRetry<T>(
  fn: () => Promise<T>,
  maxRetries = 3
): Promise<T> {
  let lastError;

  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;

      // Only retry on rate limits and server errors
      if (error.code === 'RATE_LIMIT_EXCEEDED' || error.type === 'server') {
        const delay = Math.min(1000 * Math.pow(2, i), 10000);
        await new Promise((resolve) => setTimeout(resolve, delay));
        continue;
      }

      // Don't retry validation or not found errors
      throw error;
    }
  }

  throw lastError;
}

// Usage
const dialogue = await withRetry(() => db.getDialogue(id));

6. Handle Immutability Gracefully

bash
RESPONSE=$(curl -s -o response.json -w "%{http_code}" \
  -X DELETE https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123/messages/msg_456 \
  -H "Authorization: Bearer DIALOGUE_DB_API_KEY")

if [ "$RESPONSE" = "409" ]; then
  ERROR_CODE=$(jq -r '.error.code' response.json)
  if [ "$ERROR_CODE" = "DIALOGUE_IMMUTABLE" ]; then
    echo "Cannot modify messages in immutable dialogues"
    echo "Consider creating a new dialogue with corrected messages"
  fi
fi
typescript
const response = await fetch(
  'https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123/messages/msg_456',
  {
    method: 'DELETE',
    headers: { 'Authorization': 'Bearer DIALOGUE_DB_API_KEY' },
  }
);

if (!response.ok) {
  const { error } = await response.json();

  if (error.code === 'DIALOGUE_IMMUTABLE') {
    console.error('Cannot modify messages in immutable dialogues');
    console.log('Consider creating a new dialogue with corrected messages');
  }
}
python
import requests

response = requests.delete(
    "https://api.dialoguedb.com/api/v1/dialogue/dlg_abc123/messages/msg_456",
    headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"}
)

if not response.ok:
    error = response.json()["error"]

    if error["code"] == "DIALOGUE_IMMUTABLE":
        print("Cannot modify messages in immutable dialogues")
        print("Consider creating a new dialogue with corrected messages")
typescript
try {
  await dialogue.deleteMessage(messageId);
} catch (error) {
  if (error.code === 'DIALOGUE_IMMUTABLE') {
    console.error('Cannot modify messages in immutable dialogues');
    console.log('Consider creating a new dialogue with corrected messages');
  }
}

SDK Error Handling

When using the official SDK, errors are automatically parsed into DialogueDBError instances with typed properties:

typescript
import { DialogueDB, DialogueDBError } from 'dialogue-db';

const db = new DialogueDB({ apiKey: 'DIALOGUE_DB_API_KEY' });

try {
  await db.getDialogue('invalid_id');
} catch (error) {
  if (error instanceof DialogueDBError) {
    console.log(error.code);       // 'DIALOGUE_NOT_FOUND'
    console.log(error.type);       // 'not_found'
    console.log(error.statusCode); // 404
    console.log(error.requestId);  // 'req_xyz'
    console.log(error.message);    // Human-readable message
  }
}

Testing Error Scenarios

Trigger Validation Errors

bash
# Missing required field
curl -X POST https://api.dialoguedb.com/api/v1/dialogue \
  -H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

# Response: 400 with MISSING_PARAMETER

Trigger Not Found Errors

bash
# Non-existent dialogue
curl -X GET https://api.dialoguedb.com/api/v1/dialogue/invalid_id \
  -H "Authorization: Bearer DIALOGUE_DB_API_KEY"

# Response: 404 with DIALOGUE_NOT_FOUND

Trigger Rate Limit Errors

bash
# Exceed rate limits
for i in {1..100}; do
  curl -X GET https://api.dialoguedb.com/api/v1/dialogue \
    -H "Authorization: Bearer DIALOGUE_DB_API_KEY"
done

# Response: 429 with RATE_LIMIT_EXCEEDED

Debugging Tips

1. Use Request IDs

Every error includes a requestId. Provide this when contacting support:

Support Request:
- Request ID: req_abc123xyz
- Error Code: INTERNAL_ERROR
- Timestamp: 2025-11-06T21:34:21Z

2. Enable Debug Logging

typescript
const client = new DialogueDB({
  apiKey: 'DIALOGUE_DB_API_KEY',
  debug: true  // Log all requests and responses
});

3. Check Response Headers

Rate limit information is in headers:

typescript
const response = await fetch(url, options);
console.log('Rate Limit:', response.headers.get('X-RateLimit-Limit'));
console.log('Remaining:', response.headers.get('X-RateLimit-Remaining'));
console.log('Reset:', response.headers.get('X-RateLimit-Reset'));

Common Errors & Solutions

ErrorCauseSolution
DIALOGUE_NOT_FOUNDDialogue doesn't exist or belongs to different projectVerify dialogue ID and project access
MESSAGE_CONTENT_EMPTYEmpty message contentEnsure content field is not empty
TOO_MANY_MESSAGESMore than messages on creationSplit into multiple requests
DIALOGUE_IMMUTABLEProject has immutability enabledCheck project settings or create new dialogue
RATE_LIMIT_EXCEEDEDToo many requestsImplement exponential backoff
PLAN_LIMIT_EXCEEDEDPlan quota exceededUpgrade plan - reads still work, only writes blocked
PROJECT_NOT_FOUNDInvalid project IDVerify project exists and is accessible

Support

If you encounter unexpected errors:

  1. Check the error code against this reference
  2. Note the requestId from the error response
  3. Contact support with the request ID and error details
  4. Include relevant code that triggered the error

For real-time support:

Built with DialogueDB