Skip to main content
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

{
  "error": {
    "type": "unauthorized",
    "message": "Missing or invalid API key"
  }
}
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
cURL
# ✅ 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 "X-Api-Key: AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc="     # wrong case
-H "API-Key: AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc="        # wrong header name
JavaScript
// ✅ Correct format
const headers = {
  'X-API-Key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc='
};

// ❌ Common mistakes
const headers = {
  'X-API-Key': ' AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc= ', // extra spaces
  'X-Api-Key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=',    // wrong case
  'API-Key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc='        // wrong header name
};
Python
# ✅ Correct format
headers = {
    'X-API-Key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc='
}

# ❌ Common mistakes
headers = {
    'X-API-Key': ' AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc= ',  # extra spaces
    'X-Api-Key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=',     # wrong case
    'API-Key': 'AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc='         # wrong header name
}
Go
// ✅ Correct format
headers := map[string]string{
    "X-API-Key": "AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=",
}

// ❌ Common mistakes
headers := map[string]string{
    "X-API-Key": " AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc= ", // extra spaces
    "X-Api-Key": "AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=",    // wrong case
    "API-Key":   "AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=",    // wrong header name
}
Rust
use reqwest::header::{HeaderMap, HeaderValue};

// ✅ Correct format
let mut headers = HeaderMap::new();
headers.insert("X-API-Key", HeaderValue::from_str("AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=").unwrap());

// ❌ Common mistakes - these will cause authentication failures
// Extra spaces, wrong case, wrong header name
Java
// ✅ 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("X-Api-Key", "AHGlPZaxDSMz8Wf1l8VRH4ObdbHiKsWFWnmRyHtiwAc=");    // wrong case
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

{
  "error": {
    "type": "forbidden",
    "message": "API key lacks required permissions for this endpoint"
  }
}
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: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 60
Solutions:
  • Implement exponential backoff (see Rate Limiting guide)
  • Check X-RateLimit-Reset header for recommended wait time
  • Distribute requests more evenly over time
  • Contact support if you need higher rate limits

Header Issues

Missing X-Idempotency-Key for POST Requests

Error:
{
  "error": {
    "type": "invalid_request",
    "message": "X-Idempotency-Key header is required for POST requests"
  }
}
Solution: Include a unique UUID in the X-Idempotency-Key header for POST requests only:
cURL
# ✅ 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
// ✅ 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
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
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
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
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:
{
  "error": {
    "type": "invalid_request",
    "message": "X-Idempotency-Key must be a valid UUID"
  }
}
Solution: Use a properly formatted UUID:
cURL
# ✅ Valid UUID formats
$(uuidgen)                                 # System command
'550e8400-e29b-41d4-a716-446655440000'    # Manual UUID

# ❌ Invalid formats
'123'
'not-a-uuid'
'550e8400e29b41d4a716446655440000'        # Missing hyphens
JavaScript
// ✅ 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
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
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
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
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:
cURL
# ✅ 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
// ✅ 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
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
import (
    "crypto/tls"
    "net/http"
)

// ✅ Certificate validation enabled (default)
client := &http.Client{
    Transport: &http.Transport{
        TLSClientConfig: &tls.Config{
            InsecureSkipVerify: false, // Default
        },
    },
}
Rust
// ✅ Certificate validation enabled by default
let client = reqwest::Client::builder()
    .danger_accept_invalid_certs(false) // Default
    .build()?;
Java
import javax.net.ssl.SSLContext;

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

Network Timeouts

Solutions:
cURL
# Set timeout values
curl --max-time 30 \
  -X GET https://api.platform.dakota.xyz/customers \
  -H "X-API-Key: your-api-key"
JavaScript
// 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
import requests

response = requests.get(
    url,
    headers={'X-API-Key': api_key},
    timeout=30  # 30 seconds
)
Go
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
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
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:
cURL
# 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
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
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
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
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
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:
cURL
# 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:
cURL
# 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
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
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
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
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
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:
cURL
# 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
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
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
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
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
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 this format:
{
  "error": {
    "type": "error_type",
    "message": "Human-readable error description",
    "details": {
      "field": "Additional context if applicable"
    }
  }
}
Common error types:
  • unauthorized - Authentication failed
  • forbidden - Access denied
  • invalid_request - Invalid request format
  • not_found - Resource doesn’t exist
  • internal_server_error - Server error
Note: Rate limiting (429 status) returns no structured error body, only HTTP status and headers.

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
  • 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