> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dakota.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

Common authentication issues and their solutions.

# HTTP Status Codes

## 401 Unauthorized

**Symptoms:**

* Request returns `401 Unauthorized`
* Error message indicates authentication failure

**Common Causes:**

### Missing or Invalid API Key

```json theme={null}
{
  "type": "https://docs.dakota.xyz/errors/authentication-error",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Missing or invalid API key",
  "instance": "/customers",
  "request_id": "req_abc123"
}
```

**Solutions:**

* Verify your API key is exactly 60 characters
* Check that you're including the `x-api-key` header
* Ensure no extra whitespace or characters in the key

```bash cURL theme={null}
# ✅ Correct format
curl -X GET https://api.platform.dakota.xyz/customers \
  -H "x-api-key: AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc="

# ❌ Common mistakes
-H "x-api-key:  AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc= "  # extra spaces
-H "API-Key: AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc="      # wrong header name
```

```javascript JavaScript theme={null}
// ✅ Correct format
const headers = {
  'x-api-key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc='
};

// ❌ Common mistakes
const headers = {
  'x-api-key': ' AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc= ', // extra spaces
  'API-Key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc='       // wrong header name
};
```

```python Python theme={null}
# ✅ Correct format
headers = {
    'x-api-key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc='
}

# ❌ Common mistakes
headers = {
    'x-api-key': ' AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc= ',  # extra spaces
    'API-Key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc='        # wrong header name
}
```

```go Go theme={null}
// ✅ Correct format
headers := map[string]string{
    "x-api-key": "AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=",
}

// ❌ Common mistakes
headers := map[string]string{
    "x-api-key": " AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc= ", // extra spaces
    "API-Key":   "AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=",   // wrong header name
}
```

```rust Rust theme={null}
use reqwest::header::{HeaderMap, HeaderValue};

// ✅ Correct format
let mut headers = HeaderMap::new();
headers.insert("x-api-key", HeaderValue::from_str("AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=").unwrap());

// ❌ Common mistakes - extra spaces or wrong header name will cause authentication failures
```

```java Java theme={null}
// ✅ Correct format
Map<String, String> headers = new HashMap<>();
headers.put("x-api-key", "AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=");

// ❌ Common mistakes
headers.put("x-api-key", " AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc= "); // extra spaces
headers.put("API-Key", "AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=");     // wrong header name
```

### Deleted or Expired API Key

**Solution:** Create a new API key in your Dakota Platform dashboard

### Wrong Environment

**Solution:** Ensure you're using the correct base URL:

* Production: `https://api.platform.dakota.xyz`

## 403 Forbidden

**Symptoms:**

* Request returns `403 Forbidden`
* API key is valid but access is denied

**Common Causes:**

### Insufficient Permissions

```json theme={null}
{
  "type": "https://docs.dakota.xyz/errors/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "API key lacks required permissions for this endpoint",
  "instance": "/customers",
  "request_id": "req_abc123"
}
```

**Solutions:**

* Check if your account has access to the requested feature
* Verify API key permissions in the Dakota Platform dashboard
* Contact support if you need additional permissions

### Account Limitations

**Solutions:**

* Complete required account verification steps
* Upgrade your account plan if needed
* Contact support for account-specific limitations

## 429 Too Many Requests

**Symptoms:**

* Request returns `429 Too Many Requests`
* No response body, only HTTP status
* Rate limit headers indicate limits exceeded

**Response Headers:**

```
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995290
Retry-After: 30
```

**Solutions:**

* Implement exponential backoff (see [Rate Limiting guide](rate-limiting))
* Check `Retry-After` header for seconds to wait before retrying
* Distribute requests more evenly over time
* Contact support if you need higher rate limits

# Header Issues

## Missing x-idempotency-key for POST Requests

**Error:**

```json theme={null}
{
  "type": "https://docs.dakota.xyz/errors/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "x-idempotency-key header is required for POST requests",
  "instance": "/customers",
  "request_id": "req_abc123"
}
```

**Solution:**
Include a unique UUID in the `x-idempotency-key` header for POST requests only:

```bash cURL theme={null}
# ✅ POST request with idempotency key
curl -X POST https://api.platform.dakota.xyz/customers \
  -H "x-api-key: your-api-key" \
  -H "x-idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"customer_type": "business", "name": "Acme Corp"}'

# ✅ GET request without idempotency key
curl -X GET https://api.platform.dakota.xyz/customers \
  -H "x-api-key: your-api-key"
```

```javascript JavaScript theme={null}
// ✅ POST request with idempotency key
fetch('https://api.platform.dakota.xyz/customers', {
  method: 'POST',
  headers: {
    'x-api-key': 'your-api-key',
    'x-idempotency-key': crypto.randomUUID(),
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({customer_type: 'business', name: 'Acme Corp'})
});

// ✅ GET request without idempotency key
fetch('https://api.platform.dakota.xyz/customers', {
  headers: {
    'x-api-key': 'your-api-key'
  }
});
```

```python Python theme={null}
import requests
import uuid

# ✅ POST request with idempotency key
response = requests.post(
    'https://api.platform.dakota.xyz/customers',
    headers={
        'x-api-key': 'your-api-key',
        'x-idempotency-key': str(uuid.uuid4()),
        'Content-Type': 'application/json'
    },
    json={'customer_type': 'business', 'name': 'Acme Corp'}
)

# ✅ GET request without idempotency key
response = requests.get(
    'https://api.platform.dakota.xyz/customers',
    headers={'x-api-key': 'your-api-key'}
)
```

```go Go theme={null}
package main

import (
    "bytes"
    "encoding/json"
    "net/http"
    "github.com/google/uuid"
)

// ✅ POST request with idempotency key
data := map[string]interface{}{
    "customer_type": "business",
    "name": "Acme Corp",
}
jsonData, _ := json.Marshal(data)

req, _ := http.NewRequest("POST", "https://api.platform.dakota.xyz/customers", bytes.NewBuffer(jsonData))
req.Header.Set("x-api-key", "your-api-key")
req.Header.Set("x-idempotency-key", uuid.New().String())
req.Header.Set("Content-Type", "application/json")

// ✅ GET request without idempotency key
req, _ = http.NewRequest("GET", "https://api.platform.dakota.xyz/customers", nil)
req.Header.Set("x-api-key", "your-api-key")
```

```rust Rust theme={null}
use reqwest::header::{HeaderMap, HeaderValue};
use serde_json::json;
use uuid::Uuid;

// ✅ POST request with idempotency key
let mut headers = HeaderMap::new();
headers.insert("x-api-key", HeaderValue::from_str("your-api-key").unwrap());
headers.insert("x-idempotency-key", HeaderValue::from_str(&Uuid::new_v4().to_string()).unwrap());
headers.insert("Content-Type", HeaderValue::from_static("application/json"));

let data = json!({
    "customer_type": "business",
    "name": "Acme Corp"
});

let client = reqwest::Client::new();
let response = client
    .post("https://api.platform.dakota.xyz/customers")
    .headers(headers)
    .json(&data)
    .send()
    .await?;

// ✅ GET request without idempotency key
let mut headers = HeaderMap::new();
headers.insert("x-api-key", HeaderValue::from_str("your-api-key").unwrap());

let response = client
    .get("https://api.platform.dakota.xyz/customers")
    .headers(headers)
    .send()
    .await?;
```

```java Java theme={null}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.URI;
import java.util.UUID;

// ✅ POST request with idempotency key
String requestBody = """
{
  "customer_type": "business",
  "name": "Acme Corp"
}
""";

HttpRequest postRequest = HttpRequest.newBuilder()
    .uri(URI.create("https://api.platform.dakota.xyz/customers"))
    .header("x-api-key", "your-api-key")
    .header("x-idempotency-key", UUID.randomUUID().toString())
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(requestBody))
    .build();

// ✅ GET request without idempotency key
HttpRequest getRequest = HttpRequest.newBuilder()
    .uri(URI.create("https://api.platform.dakota.xyz/customers"))
    .header("x-api-key", "your-api-key")
    .GET()
    .build();
```

## Invalid Idempotency Key Format

**Error:**

```json theme={null}
{
  "type": "https://docs.dakota.xyz/errors/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "x-idempotency-key must be a valid UUID",
  "instance": "/customers",
  "request_id": "req_abc123"
}
```

**Solution:**
Use a properly formatted UUID:

```bash cURL theme={null}
# ✅ Valid UUID formats
$(uuidgen)                                 # System command
'550e8400-e29b-41d4-a716-446655440000'    # Manual UUID

# ❌ Invalid formats
'123'
'not-a-uuid'
'550e8400e29b41d4a716446655440000'        # Missing hyphens
```

```javascript JavaScript theme={null}
// ✅ Valid UUID formats
'550e8400-e29b-41d4-a716-446655440000'
crypto.randomUUID()                        // Browser
require('uuid').v4()                      // Node.js

// ❌ Invalid formats
'123'
'not-a-uuid'
'550e8400e29b41d4a716446655440000'       // Missing hyphens
```

```python Python theme={null}
import uuid

# ✅ Valid UUID formats
str(uuid.uuid4())                         # Standard library
'550e8400-e29b-41d4-a716-446655440000'    # Manual UUID

# ❌ Invalid formats
'123'
'not-a-uuid'
'550e8400e29b41d4a716446655440000'        # Missing hyphens
```

```go Go theme={null}
import "github.com/google/uuid"

// ✅ Valid UUID formats
uuid.New().String()                       // Google UUID library
"550e8400-e29b-41d4-a716-446655440000"    // Manual UUID

// ❌ Invalid formats
"123"
"not-a-uuid"
"550e8400e29b41d4a716446655440000"        // Missing hyphens
```

```rust Rust theme={null}
use uuid::Uuid;

// ✅ Valid UUID formats
Uuid::new_v4().to_string()                // UUID crate
"550e8400-e29b-41d4-a716-446655440000"    // Manual UUID

// ❌ Invalid formats
"123"
"not-a-uuid"
"550e8400e29b41d4a716446655440000"        // Missing hyphens
```

```java Java theme={null}
import java.util.UUID;

// ✅ Valid UUID formats
UUID.randomUUID().toString()              // Standard library
"550e8400-e29b-41d4-a716-446655440000"    // Manual UUID

// ❌ Invalid formats
"123"
"not-a-uuid"
"550e8400e29b41d4a716446655440000"        // Missing hyphens
```

# Connection Issues

## SSL/TLS Errors

**Symptoms:**

* Connection fails with SSL certificate errors
* "Unable to verify SSL certificate" messages

**Solutions:**

```bash cURL theme={null}
# ✅ Certificate validation enabled (default)
curl -X GET https://api.platform.dakota.xyz/customers \
  -H "x-api-key: your-api-key"

# If you have custom certificates
curl --cacert /path/to/certificate.pem \
  -X GET https://api.platform.dakota.xyz/customers \
  -H "x-api-key: your-api-key"
```

```javascript JavaScript theme={null}
// ✅ Certificate validation is handled by the browser/Node.js
const https = require('https');
const agent = new https.Agent({
  rejectUnauthorized: true  // Default, but make it explicit
});

fetch(url, { agent }); // Node.js only
```

```python Python theme={null}
import requests

# ✅ Certificate validation enabled (default)
response = requests.get(url, verify=True)

# If you have custom certificates
response = requests.get(url, verify='/path/to/certificate.pem')
```

```go Go theme={null}
import (
    "crypto/tls"
    "net/http"
)

// ✅ Certificate validation enabled (default)
client := &http.Client{
    Transport: &http.Transport{
        TLSClientConfig: &tls.Config{
            InsecureSkipVerify: false, // Default
        },
    },
}
```

```rust Rust theme={null}
// ✅ Certificate validation enabled by default
let client = reqwest::Client::builder()
    .danger_accept_invalid_certs(false) // Default
    .build()?;
```

```java Java theme={null}
import javax.net.ssl.SSLContext;

// ✅ Certificate validation enabled by default
HttpClient client = HttpClient.newBuilder()
    .sslContext(SSLContext.getDefault())
    .build();
```

## Network Timeouts

**Solutions:**

```bash cURL theme={null}
# Set timeout values
curl --max-time 30 \
  -X GET https://api.platform.dakota.xyz/customers \
  -H "x-api-key: your-api-key"
```

```javascript JavaScript theme={null}
// Note: fetch() doesn't support timeout directly, use AbortController
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);

try {
  const response = await fetch(url, {
    headers: { 'x-api-key': apiKey },
    signal: controller.signal
  });
  clearTimeout(timeoutId);
} catch (error) {
  clearTimeout(timeoutId);
}
```

```python Python theme={null}
import requests

response = requests.get(
    url,
    headers={'x-api-key': api_key},
    timeout=30  # 30 seconds
)
```

```go Go theme={null}
import (
    "context"
    "net/http"
    "time"
)

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
req.Header.Set("x-api-key", apiKey)

client := &http.Client{}
resp, err := client.Do(req)
```

```rust Rust theme={null}
use std::time::Duration;

let client = reqwest::Client::builder()
    .timeout(Duration::from_secs(30))
    .build()?;

let response = client
    .get(url)
    .header("X-API-Key", api_key)
    .send()
    .await?;
```

```java Java theme={null}
import java.time.Duration;

HttpClient client = HttpClient.newBuilder()
    .connectTimeout(Duration.ofSeconds(30))
    .build();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(url))
    .timeout(Duration.ofSeconds(30))
    .header("X-API-Key", apiKey)
    .GET()
    .build();
```

# Debugging Steps

## 1. Verify API Key Format

Check your API key meets the requirements:

```bash cURL theme={null}
# Check API key length
echo "${#DAKOTA_API_KEY}"  # Should output 60

# Basic validation
if [ ${#DAKOTA_API_KEY} -ne 60 ]; then
  echo "Error: API key must be exactly 60 characters"
fi
```

```javascript JavaScript theme={null}
function validateApiKey(apiKey) {
  if (!apiKey) {
    throw new Error('API key is required');
  }
  
  if (apiKey.length !== 60) {
    throw new Error(`API key must be exactly 60 characters, got ${apiKey.length}`);
  }
  
  // Check if it's base64 encoded
  const base64Regex = /^[A-Za-z0-9+/]+=*$/;
  if (!base64Regex.test(apiKey)) {
    throw new Error('API key must be base64 encoded');
  }
  
  return true;
}
```

```python Python theme={null}
import re
import base64

def validate_api_key(api_key):
    if not api_key:
        raise ValueError('API key is required')
    
    if len(api_key) != 60:
        raise ValueError(f'API key must be exactly 60 characters, got {len(api_key)}')
    
    # Check if it's base64 encoded
    base64_regex = re.compile(r'^[A-Za-z0-9+/]+=*$')
    if not base64_regex.match(api_key):
        raise ValueError('API key must be base64 encoded')
    
    return True
```

```go Go theme={null}
import (
    "encoding/base64"
    "fmt"
    "regexp"
)

func validateAPIKey(apiKey string) error {
    if apiKey == "" {
        return fmt.Errorf("API key is required")
    }
    
    if len(apiKey) != 60 {
        return fmt.Errorf("API key must be exactly 60 characters, got %d", len(apiKey))
    }
    
    // Check if it's base64 encoded
    base64Regex := regexp.MustCompile(`^[A-Za-z0-9+/]+=*$`)
    if !base64Regex.MatchString(apiKey) {
        return fmt.Errorf("API key must be base64 encoded")
    }
    
    return nil
}
```

```rust Rust theme={null}
use regex::Regex;

fn validate_api_key(api_key: &str) -> Result<bool, String> {
    if api_key.is_empty() {
        return Err("API key is required".to_string());
    }
    
    if api_key.len() != 60 {
        return Err(format!(
            "API key must be exactly 60 characters, got {}", 
            api_key.len()
        ));
    }
    
    // Check if it's base64 encoded
    let base64_regex = Regex::new(r"^[A-Za-z0-9+/]+=*$").unwrap();
    if !base64_regex.is_match(api_key) {
        return Err("API key must be base64 encoded".to_string());
    }
    
    Ok(true)
}
```

```java Java theme={null}
import java.util.regex.Pattern;

public class APIKeyValidator {
    private static final Pattern BASE64_PATTERN = 
        Pattern.compile("^[A-Za-z0-9+/]+=*$");
    
    public static boolean validateApiKey(String apiKey) throws IllegalArgumentException {
        if (apiKey == null || apiKey.isEmpty()) {
            throw new IllegalArgumentException("API key is required");
        }
        
        if (apiKey.length() != 60) {
            throw new IllegalArgumentException(
                String.format("API key must be exactly 60 characters, got %d", apiKey.length())
            );
        }
        
        // Check if it's base64 encoded
        if (!BASE64_PATTERN.matcher(apiKey).matches()) {
            throw new IllegalArgumentException("API key must be base64 encoded");
        }
        
        return true;
    }
}
```

## 2. Test with cURL

Use cURL to isolate issues from your code:

```bash cURL theme={null}
# Test GET request
curl -v -X GET https://api.platform.dakota.xyz/customers \
  -H "x-api-key: YOUR_API_KEY"

# Test POST request
curl -v -X POST https://api.platform.dakota.xyz/customers \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"customer_type": "business", "name": "Test Company"}'
```

The `-v` flag provides verbose output showing the full HTTP exchange.

## 3. Check Response Headers

Always inspect response headers for debugging information:

```bash cURL theme={null}
# Use -v for verbose output including headers
curl -v -X GET https://api.platform.dakota.xyz/customers \
  -H "x-api-key: YOUR_API_KEY"

# Use -i to include response headers in output
curl -i -X GET https://api.platform.dakota.xyz/customers \
  -H "x-api-key: YOUR_API_KEY"
```

```javascript JavaScript theme={null}
async function debugRequest(url, options) {
  const response = await fetch(url, options);
  
  console.log('Status:', response.status);
  console.log('Headers:');
  response.headers.forEach((value, key) => {
    console.log(`  ${key}: ${value}`);
  });
  
  const body = await response.text();
  console.log('Body:', body);
  
  return response;
}
```

```python Python theme={null}
import requests

def debug_request(url, **kwargs):
    response = requests.request(**kwargs, url=url)
    
    print(f'Status: {response.status_code}')
    print('Headers:')
    for key, value in response.headers.items():
        print(f'  {key}: {value}')
    
    print(f'Body: {response.text}')
    
    return response
```

```go Go theme={null}
import (
    "fmt"
    "io"
    "net/http"
    "net/http/httputil"
)

func debugRequest(req *http.Request) (*http.Response, error) {
    // Dump the request
    reqDump, _ := httputil.DumpRequestOut(req, true)
    fmt.Printf("REQUEST:\n%s\n", reqDump)
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    
    // Dump the response
    respDump, _ := httputil.DumpResponse(resp, true)
    fmt.Printf("RESPONSE:\n%s\n", respDump)
    
    return resp, nil
}
```

```rust Rust theme={null}
use reqwest::Response;

async fn debug_request(response: Response) {
    println!("Status: {}", response.status());
    println!("Headers:");
    for (key, value) in response.headers() {
        println!("  {}: {:?}", key, value);
    }
    
    let body = response.text().await.unwrap_or_default();
    println!("Body: {}", body);
}
```

```java Java theme={null}
import java.net.http.HttpResponse;

public void debugRequest(HttpResponse<String> response) {
    System.out.printf("Status: %d%n", response.statusCode());
    System.out.println("Headers:");
    response.headers().map().forEach((key, values) -> {
        values.forEach(value -> {
            System.out.printf("  %s: %s%n", key, value);
        });
    });
    
    System.out.printf("Body: %s%n", response.body());
}
```

## 4. Enable Request Logging

Log your requests to identify issues:

```bash cURL theme={null}
# Log to file for analysis
curl -v -X GET https://api.platform.dakota.xyz/customers \
  -H "x-api-key: YOUR_API_KEY" \
  2>&1 | tee request.log

# Remove sensitive data from logs
sed -i 's/x-api-key: .*/x-api-key: [REDACTED]/g' request.log
```

```javascript JavaScript theme={null}
function logRequest(url, options) {
  const safeHeaders = { ...options.headers };
  delete safeHeaders['x-api-key']; // Don't log sensitive data
  
  console.log('Making request:', {
    url,
    method: options.method || 'GET',
    headers: safeHeaders,
    bodyLength: options.body ? options.body.length : 0
  });
}
```

```python Python theme={null}
import logging
from urllib.parse import urlparse

def log_request(method, url, headers, body=None):
    safe_headers = headers.copy()
    if 'x-api-key' in safe_headers:
        safe_headers['x-api-key'] = '[REDACTED]'
    
    parsed_url = urlparse(url)
    
    logging.info('Making request: %s', {
        'method': method,
        'url': f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}",
        'headers': safe_headers,
        'body_length': len(body) if body else 0
    })
```

```go Go theme={null}
import (
    "log"
    "net/url"
)

func logRequest(method, urlStr string, headers map[string]string, bodyLength int) {
    safeHeaders := make(map[string]string)
    for k, v := range headers {
        if k == "x-api-key" {
            safeHeaders[k] = "[REDACTED]"
        } else {
            safeHeaders[k] = v
        }
    }
    
    parsedURL, _ := url.Parse(urlStr)
    
    log.Printf("Making request: method=%s url=%s://%s%s headers=%v bodyLength=%d",
        method,
        parsedURL.Scheme,
        parsedURL.Host,
        parsedURL.Path,
        safeHeaders,
        bodyLength,
    )
}
```

```rust Rust theme={null}
use std::collections::HashMap;
use log::info;
use url::Url;

fn log_request(method: &str, url: &str, headers: &HashMap<String, String>, body_length: usize) {
    let mut safe_headers = headers.clone();
    if safe_headers.contains_key("x-api-key") {
        safe_headers.insert("x-api-key".to_string(), "[REDACTED]".to_string());
    }
    
    if let Ok(parsed_url) = Url::parse(url) {
        info!(
            "Making request: method={} url={}://{}{} headers={:?} body_length={}",
            method,
            parsed_url.scheme(),
            parsed_url.host_str().unwrap_or(""),
            parsed_url.path(),
            safe_headers,
            body_length
        );
    }
}
```

```java Java theme={null}
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

public class RequestLogger {
    private static final Logger logger = Logger.getLogger(RequestLogger.class.getName());
    
    public static void logRequest(String method, String url, Map<String, String> headers, int bodyLength) {
        Map<String, String> safeHeaders = new HashMap<>(headers);
        if (safeHeaders.containsKey("x-api-key")) {
            safeHeaders.put("x-api-key", "[REDACTED]");
        }
        
        try {
            URI uri = URI.create(url);
            logger.info(String.format(
                "Making request: method=%s url=%s://%s%s headers=%s bodyLength=%d",
                method,
                uri.getScheme(),
                uri.getHost(),
                uri.getPath(),
                safeHeaders,
                bodyLength
            ));
        } catch (Exception e) {
            logger.warning("Failed to parse URL for logging: " + url);
        }
    }
}
```

# Error Response Format

All Dakota Platform API errors follow [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457.html) format with `application/problem+json` content type:

```json theme={null}
{
  "type": "https://docs.dakota.xyz/errors/authentication-error",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Missing or invalid API key",
  "instance": "/customers",
  "request_id": "req_abc123"
}
```

Common error types (the `type` field URI):

* `https://docs.dakota.xyz/errors/authentication-error` - Authentication failed (401)
* `https://docs.dakota.xyz/errors/forbidden` - Access denied (403)
* `https://docs.dakota.xyz/errors/validation-error` - Invalid request format (400)
* `https://docs.dakota.xyz/errors/not-found` - Resource doesn't exist (404)
* `https://docs.dakota.xyz/errors/rate-limited` - Too many requests (429)
* `https://docs.dakota.xyz/errors/internal-error` - Server error (500)

Rate limiting (429) also returns RFC 9457 Problem Details:

```json theme={null}
{
  "type": "https://docs.dakota.xyz/errors/rate-limited",
  "title": "Rate Limited",
  "status": 429,
  "detail": "Too many requests. Please retry later.",
  "instance": "/customers",
  "request_id": "req_xyz789"
}
```

# Getting Help

If you're still experiencing issues:

1. **Check the API status page** for any ongoing issues
2. **Review recent changes** to your code or configuration
3. **Test with minimal examples** to isolate the problem
4. **Contact support** with:
   * Complete error messages
   * Request/response logs (with API keys removed)
   * Steps to reproduce the issue
   * A relevant Request ID from the response headers, if available

## Support Information

* Email: [support@dakota.xyz](mailto:support@dakota.xyz)
* Include "API Authentication Issue" in the subject line
* Provide relevant logs with sensitive information removed
* Mention this troubleshooting guide and what you've already tried

# Quick Checklist

Before contacting support, verify:

* [ ] API key is exactly 60 characters
* [ ] Using correct header name: `x-api-key`
* [ ] Including `x-idempotency-key` for POST requests only
* [ ] Using HTTPS base URL: `https://api.platform.dakota.xyz`
* [ ] API key is active in your dashboard
* [ ] Account has necessary permissions
* [ ] Not hitting rate limits
* [ ] Request format matches API documentation
