AWorld Lab API Reference
API Reference
App API (Consumer)Dashboard API (Admin)
API Reference
App API (Consumer)Dashboard API (Admin)
  1. Overview
  • Overview
    • Getting Started
    • Authentication
    • API Architecture
    • Server-side Integration Guide
  1. Overview

API Architecture

API Domains#

Auth: https://auth.aworld.cloud
API: https://api.aworld.cloud
Dashboard (Admin) API: https://api.aworld.cloud/dashboard/v1/*
App (Consumer) API: https://api.aworld.cloud/app/v1/*

Multi-Tenant Architecture#

AWorld Lab uses a hierarchical multi-tenant model where each organization operates in isolation.

Hierarchy#

Platform
└── Account (Tenant)
    └── Workspace
        └── User
Platform: Top-level AWorld system
Account: Isolated tenant (organization/company)
Workspace: Environment within account (dev/staging/prod)
User: Workspace-scoped user with specific roles

Data Isolation#

Each account's data is logically separated:
Accounts cannot access each other's data
Isolation enforced at database and API layers
Each workspace within an account is also isolated
workspaceId in JWT token controls data access
Critical: All API requests validate workspaceId claim matches requested resources. Cross-workspace access is blocked at API gateway level.

Workspaces#

Workspaces provide isolated environments within an account.

Common Patterns#

Development: Build and test features
Staging: Pre-production QA
Production: Live environment for end-users
Or organized by:
Teams/departments
Client projects
Business units
Application types

Workspace Resources#

Each workspace has isolated:
Users: Workspace-scoped with specific roles
Configuration: Workspace-specific settings
Data: Missions, activities, leaderboards, users
Credentials: Separate Cognito app client per workspace
Logs: Workspace-specific operational data

Best Practices#

1.
Naming: Use consistent patterns (e.g., project-env, team-workspace)
2.
Separation: Keep dev/staging/prod completely separate
3.
Access: Limit production access to essential personnel
4.
Cleanup: Archive unused workspaces regularly

API Contexts#

AWorld Lab exposes two API contexts, each with different access levels, purposes, and separate client credentials.
AspectDashboard API (Admin/Management)App API (Consumer/User-facing)
Base URL/dashboard/v1/*/app/v1/*
AudienceAdministrators, content managersEnd users, consumer applications
Auth LevelAdmin/EditorUser-level
Server-side CredentialsDashboard clientId/clientSecretApp clientId/clientSecret
Required ClaimsuserId, workspaceId, roleuserId, workspaceId
Use CasesUser management, content creation & configurationMissions, leaderboards, activities
Important for server-side integrations: Each API context requires its own set of client credentials. A single set of credentials cannot access both contexts. See the Server-side Integration Guide for the complete integration flow.

Why Two Separate API Contexts?#

The separation exists for security and least-privilege reasons. Administrative operations (creating users, managing content, publishing missions) require elevated privileges that should never be available to consumer-scoped tokens. By issuing separate credentials per context:
A compromised App token cannot perform admin operations
Consumer applications never have access to management endpoints
Each credential set has minimal scopes for its purpose

Dashboard API (Admin/Management)#

Administrative and content management endpoints. Used by workspace administrators and by third-party backends (via server-side integration) for operations like user registration and content configuration.
Example endpoints:
GET    /dashboard/v1/missions
POST   /dashboard/v1/missions
PUT    /dashboard/v1/missions/{missionId}
POST   /dashboard/v1/missions/{missionId}/publish
POST   /dashboard/v1/activities
GET    /dashboard/v1/users
POST   /dashboard/v1/users
Required token claims: userId, workspaceId, role (admin/editor)

App API (Consumer/User-facing)#

Consumer-facing endpoints for end users. When accessed via server-side integration, use the x-user-id or x-external-user-id header to operate on behalf of a specific user (see User Impersonation).
Example endpoints:
GET    /app/v1/missions
GET    /app/v1/missions/{missionId}
GET    /app/v1/activities
GET    /app/v1/users/me
GET    /app/v1/runtime-leaderboards
GET    /app/v1/runtime-leaderboards/{id}/rankings
POST   /app/v1/quiz/{quizId}/submit
Required token claims: userId, workspaceId

REST API Conventions#

Resource Naming#

Plural nouns: /missions, /activities, /leaderboards
Kebab-case: /runtime-leaderboards, /quiz-submissions
Lowercase: No camelCase or PascalCase in paths

HTTP Methods#

MethodPurposeExample
GETRetrieve resource(s)GET /missions
POSTCreate resource or execute actionPOST /missions, POST /missions/{id}/publish
PUTFull resource replacementPUT /missions/{id}
PATCHPartial resource updatePATCH /missions/{id}
DELETEDelete resourceDELETE /missions/{id}

Action Endpoints#

Non-CRUD operations use POST with action name:
POST   /missions/{id}/publish
POST   /missions/{id}/archive
POST   /missions/{id}/duplicate
POST   /quiz/{id}/submit
POST   /leaderboards/{id}/reset

Path vs Query Parameters#

Path parameters: Resource identifiers
GET /missions/{missionId}
GET /activities/{activityId}
Query parameters: Filtering, pagination, sorting
GET /missions?status=published&limit=20&offset=0
GET /users?role=admin&workspaceId=abc123

Example REST Endpoint Structure#

# List resources
GET    /missions?limit=20&offset=0

# Get single resource
GET    /missions/{missionId}

# Create resource (Dashboard only)
POST   /missions
Body: { "name": "Mission Name", "type": "quiz", ... }

# Update resource (Dashboard only)
PUT    /missions/{missionId}
Body: { "name": "Updated Name", ... }

# Partial update (Dashboard only)
PATCH  /missions/{missionId}
Body: { "status": "published" }

# Execute action
POST   /missions/{missionId}/publish
Body: { "scheduledAt": "2026-03-01T00:00:00Z" }

# Delete resource (Dashboard only)
DELETE /missions/{missionId}

Common Patterns#

Pagination#

List endpoints use connection pattern with limit, offset, and nextToken.
Request:
Response:
{
  "items": [
    { "id": "mission1", "name": "..." },
    { "id": "mission2", "name": "..." }
  ],
  "nextToken": "eyJsYXN0SXRlbUlkIjoibWlzc2lvbjIwIn0",
  "total": 150
}
Next page:
Important: nextToken must be used with the same limit value. Don't mix tokens from different limits.

Idempotency#

Mutations that create or modify resources support idempotency via x-idempotency-key header.
Request:
Behavior:
First request: Processes normally, returns 201 Created
Duplicate requests (same key, within 5 minutes): Returns cached response with x-idempotency-cache-hit: true header
After 5 minutes: Cache expires, request processed again (may fail if resource exists)
Best practice: Generate idempotency keys using UUIDs or similar unique identifiers.

Versioning#

APIs use explicit versioning in URL path (/v1/, /v2/):
https://api.aworld.cloud/app/v1/missions
https://api.aworld.cloud/dashboard/v1/missions
Version changes occur only for breaking changes. Non-breaking updates are deployed without version increments.

Response Compression#

Enable gzip compression for faster transfers:
Request:
Accept-Encoding: gzip
APIs automatically compress responses when this header is present.

Caching#

Read-only queries leverage ElastiCache for performance:
Frequently accessed mission configurations cached
User profile data cached temporarily
Leaderboards updated in real-time (not cached)
Cache automatically invalidated on resource updates
Cache control: Responses include standard HTTP cache headers (Cache-Control, ETag).

Rate Limiting#

Current status (pre-alpha): No rate limits enforced
Future implementation: Per-workspace throttling based on:
Requests per second (RPS)
Requests per minute (RPM)
Concurrent connections

Data Validation#

ID Formats#

All IDs use nanoid format (21 characters, URL-safe):
userId: "V1StGXR8_Z5jdHi6B-myT"
missionId: "3z4v7K9pL2qR5sT8xY1nW"
workspaceId: "abc_123-xyz"

String Rules#

FieldMin LengthMax LengthPattern
Name250Unicode letters, spaces, hyphens, apostrophes
Email5254Valid email format
Description02000UTF-8 text
Name validation:
Supports multiple scripts (Latin, Chinese, Arabic, etc.)
No consecutive spaces
Cannot start/end with spaces

Timestamps#

All timestamps use ISO 8601 format in UTC:
{
  "createdAt": "2026-02-17T14:30:00Z",
  "updatedAt": "2026-02-17T15:45:30Z",
  "scheduledAt": "2026-03-01T00:00:00Z"
}

Language Codes#

ISO 639-1 language codes:
"en" (English)
"it" (Italian)
"fr" (French)
"es" (Spanish)
"zh-CN" (Chinese Simplified)
"zh-TW" (Chinese Traditional)

Timezones#

IANA timezone identifiers:
"UTC"
"Europe/Rome"
"America/New_York"
"Asia/Tokyo"

Error Handling#

HTTP Status Codes#

CodeMeaningWhen Used
200OKSuccessful GET/PUT/PATCH
201CreatedSuccessful POST (resource created)
204No ContentSuccessful DELETE
400Bad RequestInvalid input, validation errors
401UnauthorizedMissing or invalid access token
403ForbiddenValid token but insufficient permissions
404Not FoundResource doesn't exist
409ConflictResource already exists, state conflict
422Unprocessable EntitySemantic validation errors
429Too Many RequestsRate limit exceeded (future)
500Internal Server ErrorUnexpected server error

Error Response Format#

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid mission name",
    "details": [
      {
        "field": "name",
        "message": "Name must be between 2 and 50 characters"
      }
    ]
  }
}

Common Error Codes#

CodeDescriptionSolution
INVALID_TOKENAccess token expired or invalidRefresh token or re-authenticate
WORKSPACE_MISMATCHToken workspaceId doesn't match requestVerify correct workspace context
INSUFFICIENT_PERMISSIONSUser lacks required roleCheck user role and permissions
RESOURCE_NOT_FOUNDRequested resource doesn't existVerify resource ID
DUPLICATE_RESOURCEResource already existsUse different identifier or update existing
VALIDATION_ERRORInput validation failedCheck error details for specific fields

Best Practices#

API Integration#

1.
Always validate workspaceId: Ensure token's workspaceId matches intended workspace
2.
Use idempotency keys: Prevent duplicate resource creation
3.
Handle token expiration: Implement automatic token refresh
4.
Request only needed fields: Minimize response payload size
5.
Implement pagination: Don't fetch all items at once
6.
Use compression: Include Accept-Encoding: gzip header
7.
Handle errors gracefully: Implement retry logic with exponential backoff

Security#

1.
Never log access tokens: Tokens contain sensitive user information
2.
Validate JWT claims: Check exp, workspaceId, and userId on every request
3.
Use HTTPS only: All API calls must use HTTPS in production
4.
Implement CSRF protection: Use state parameter in OAuth flows
5.
Rotate credentials: Regularly update client secrets
6.
Monitor suspicious activity: Log failed auth attempts

Performance#

1.
Cache responses: Leverage HTTP cache headers
2.
Batch requests: Combine multiple operations when possible
3.
Use pagination: Limit result sets to reasonable sizes
4.
Minimize payload: Request only required fields
5.
Implement connection pooling: Reuse HTTP connections
6.
Monitor latency: Track API response times

Data Management#

1.
Use ISO 8601 timestamps: All dates in UTC
2.
Validate IDs: Check format before making requests
3.
Handle timezone conversions: Convert to user's timezone in UI
4.
Support multiple languages: Use lang claim from token
5.
Implement soft deletes: Mark resources as deleted instead of removing
6.
Audit changes: Log all create/update/delete operations

OpenAPI Specifications#

Complete REST endpoint documentation is available in OpenAPI format:
Location: /packages/schemas/{context}/v1/openapi.json in monorepo
Contexts:
Dashboard: /packages/schemas/dashboard/v1/openapi.json
App: /packages/schemas/app/v1/openapi.json
Use these specs with tools like Swagger UI, Postman, or code generators for complete endpoint reference.
Modified at 2026-03-19 16:03:14
Previous
Authentication
Next
Server-side Integration Guide
Built with