Esc

Type to search across all documentation pages...

/ Developer Docs
Feedback Docs Home Landing Page Log in

WildwoodAPI Reference

Complete REST API documentation for WildwoodAPI — a .NET 9 backend providing authentication, AI services, user management, and security for multi-tenant applications.

Base URL The API base URL depends on your deployment. For local development the default is https://localhost:7046. Check your launchSettings.json or appsettings.json for the configured port.
Swagger / OpenAPI WildwoodAPI includes a built-in Swagger UI for interactive API exploration during local development. To enable it, set "Swagger:Enabled": true in your appsettings.Development.json, then navigate to /swagger. Swagger is disabled by default in production for security.

Authentication

WildwoodAPI uses JWT Bearer tokens for authentication. After logging in via POST /api/auth/login, include the returned token in every subsequent request:

curl -X GET https://localhost:7046/api/ai/configurations \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json"
Auth Required All endpoints require a valid Authorization: Bearer {token} header unless explicitly marked as Anonymous. Requests without a valid token receive a 401 Unauthorized response.

Multi-Tenant Scoping

WildwoodAPI is a multi-tenant platform. Every user belongs to one or more applications identified by an AppId. When you log in, you pass the appId in the request body. The JWT token returned contains embedded claims:

Claim Description
sub User ID (unique identifier)
email User's email address
app_id Application ID the user authenticated against
company_id Company the user belongs to
role User roles (e.g., Admin, CompanyAdmin, User)

All data queries are automatically scoped by these claims. A user can only access data belonging to their application and company.

Content Type

All request and response bodies use JSON. Set the Content-Type header to application/json on every request that includes a body.

Common Response Format

Success Responses

Successful responses return the requested data directly in the body with an appropriate HTTP status code:

// 200 OK - Data returned
{
  "id": "abc-123",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane@example.com"
}

// 201 Created - Resource created (includes Location header)
// 204 No Content - Action succeeded with no body

Error Responses

Error responses follow a consistent JSON structure:

{
  "error": "InvalidCredentials",
  "message": "The email or password you entered is incorrect.",
  "details": "Please check your password and try again."
}
Field Type Description
error string Machine-readable error code (e.g., InvalidCredentials, UserNotFound)
message string Human-readable error message
details string? Optional additional context or guidance

HTTP Status Codes

Code Meaning When Used
200 OK Successful GET, PUT, POST, or DELETE
201 Created Resource successfully created (e.g., new session)
400 Bad Request Invalid input, validation failure, or malformed request
401 Unauthorized Missing or invalid JWT token
403 Forbidden Valid token but insufficient permissions (wrong role or app)
404 Not Found Requested resource does not exist
409 Conflict Resource already exists (e.g., duplicate email on registration)
429 Too Many Requests Rate limit exceeded (includes Retry-After header)
500 Internal Server Error Unexpected server error

Rate Limiting

Certain endpoints enforce per-user rate limits. The AI chat endpoint (POST /api/ai/chat) uses a PerUserAI rate limiting policy. When a limit is exceeded the API returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait.

Token Refresh

JWT tokens expire after a configured duration. Use the POST /api/auth/refresh-token endpoint with your refresh token to obtain a new JWT without re-authenticating. The refresh token is also set as an httpOnly cookie named refreshToken.

Example: Full Login Flow

# 1. Login and obtain tokens
curl -X POST https://localhost:7046/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "YourPassword123!",
    "appId": "d6e61c7a-eec5-4164-a004-9b99eb5eb6de",
    "platform": "web",
    "deviceInfo": "Chrome 120"
  }'

# 2. Use the JWT token for authenticated requests
curl -X GET https://localhost:7046/api/ai/configurations \
  -H "Authorization: Bearer eyJhbGciOi..."

# 3. Refresh the token when it expires
curl -X POST https://localhost:7046/api/auth/refresh-token \
  -H "Content-Type: application/json" \
  -d '{ "refreshToken": "abc123..." }'
// 1. Login and obtain tokens
var client = new HttpClient { BaseAddress = new Uri("https://localhost:7046") };

var loginRequest = new
{
    email = "user@example.com",
    password = "YourPassword123!",
    appId = "d6e61c7a-eec5-4164-a004-9b99eb5eb6de",
    platform = "web",
    deviceInfo = "Console App"
};

var response = await client.PostAsJsonAsync("/api/auth/login", loginRequest);
var result = await response.Content.ReadFromJsonAsync<LoginResponse>();

// 2. Use the JWT token for authenticated requests
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", result.JwtToken);

var configs = await client.GetFromJsonAsync<List<AIConfiguration>>(
    "/api/ai/configurations");

// 3. Refresh the token when it expires
var refreshResponse = await client.PostAsJsonAsync(
    "/api/auth/refresh-token",
    new { refreshToken = result.RefreshToken });

API Sections

Last updated: February 2026