AILAT API v1.0.1
An adaptive testing API that measures AI literacy across four dimensions. Create assessments, submit answers, and retrieve personalized results from your LMS, HR tool, or custom application.
Base URL
https://ailat.io/api/v1
Auth
Bearer token
Rate limit
100 req / min
Getting started
Overview
The AILAT API powers the AI Literacy Assessment Test — an IRT-informed adaptive assessment. A single integration exposes 20-question sessions, adaptive item selection, evaluated open-ended responses, and a full results profile with a personalized learning path.
https://ailat.io/api/v1Authentication
Every request requires a bearer token. Use the API inquiry form to request one.
Authorization: Bearer YOUR_API_TOKENQuick start
A typical integration follows five steps.
- 1Create. POST /assessments — returns the first question.
- 2Present. Render the returned question to the user.
- 3Submit. POST /assessments/{id}/answers — the response includes the next question.
- 4Repeat. Continue steps 2 – 3 until assessment_complete: true.
- 5Fetch. GET /assessments/{id}/results — full literacy profile.
Phases
| Phase | Questions | Description |
|---|---|---|
| Calibration | 5 | Mixed-difficulty baseline across all dimensions. |
| Adaptive | 10 | 2PL item-information selection targeting the weakest area. Includes 2 open-ended. |
| Scenario | 5 | Industry-specific context with 1 open-ended capstone. |
Core concepts
Assessment lifecycle
Sessions move through a small state machine. Pausing is client-initiated (there is no automatic idle pause); resume with a status update before submitting more answers. Retention is governed by the privacy notice: 7 days idle for in-progress or paused sessions, 90 days after completion.
created ──▶ in_progress ──▶ pending_results ──▶ completed
│ ▲ (on retry)
▼ │
paused ────────────┘
│
▼ (closed bank exhausted)
incomplete_inventory — answers kept, no literacy level awarded| Status | Meaning |
|---|---|
in_progress | Assessment is active and accepting answers. |
paused | Paused by the client via PUT /status. |
completed | All questions answered and results are available. |
pending_results | All questions answered; results are still being generated. |
incomplete_inventory | The approved question bank ran out of eligible items (closed generated-item policy). Answers are kept; GET /results returns incomplete: true with no literacy level. |
HTTP status codes
Errors share a consistent shape. Check recovery_action for user-facing guidance.
| Code | Meaning |
|---|---|
200 | Success. |
202 | Accepted — results are still being generated; retry after delay. |
400 | Bad request — invalid parameters, idle session, or completed assessment. |
401 | Unauthorized — invalid or missing token. |
403 | Forbidden — token lacks access to the requested resource. |
404 | Not found — assessment or resource does not exist. |
429 | Rate limited — check Retry-After header. |
500 | Server error. |
501 | Not implemented — feature planned for v1.1. |
503 | Service unavailable — retry in 30s. |
{
"success": false,
"error": "ValidationError",
"message": "Human-readable description",
"details": { },
"recovery_action": "What to do next"
}Rate limits
100 requests per minute per API token. Exceeding the limit returns 429 with a Retry-After header. Use exponential backoff with jitter when retrying.
| Header | Value |
|---|---|
X-RateLimit-Limit | 100 |
X-RateLimit-Remaining | Approximate remaining requests. |
Endpoints
Endpoints
Each endpoint speaks JSON and returns the shape shown. {id} is the assessment identifier returned from the create call.
Create assessment
Creates a new assessment and returns the first question.
Request
| Field | Type | Required | Description |
|---|---|---|---|
industry | enum | Yes | One of the industry values listed below. |
role | string | Yes | User's professional role. |
motivation | enum | No | One of the motivation values listed below. |
organization_id | string | No | Organization identifier; org-tagged assessments are access-controlled and require a matching org-scoped API token. |
user_id | string | No | User identifier for tracking. |
Response
{
"success": true,
"assessment_id": "asmt_abcdef123456",
"status": "in_progress",
"current_question": {
"question_id": "Q1",
"question_text": "...",
"question_type": "multiple_choice",
"options": {
"A": "...",
"B": "...",
"C": "...",
"D": "..."
},
"dimension": "CONCEPTUAL_KNOWLEDGE"
},
"progress": {
"questions_completed": 0,
"total_questions": 20,
"percent_complete": 0
}
}Valid industry values
| Value |
|---|
Academia & Education |
Agriculture, Forestry & Fishing |
Arts, Entertainment & Media |
Construction & Real Estate |
Energy & Utilities |
Financial Services |
Government & Public Sector |
Healthcare & Social Services |
Hospitality & Tourism |
Information Technology |
Legal Services |
Manufacturing |
Professional Services |
Retail & Consumer Goods |
Science & Research |
Telecommunications |
Transportation & Logistics |
Wholesale & Distribution |
General |
Valid motivation values
| Value | Meaning |
|---|---|
Professional Development | For current job role improvement |
Career Transition | Moving to a new AI-related role |
Academic Learning | For educational purposes |
Leadership | For managing teams using AI |
Personal Interest | General curiosity about AI |
Organizational Assessment | Understanding team capabilities |
Certification | Preparing for formal certification |
Required Training | Mandated by organization |
Get assessment state
Returns the current question and progress. Use this to resume after a page reload.
Status-specific behavior
| Assessment status | Behavior |
|---|---|
in_progress / paused | Returns the current question and progress. |
completed | Returns 400 with results_url in the body. Follow the URL to fetch results. |
pending_results | Returns 400 with results_url. Retry GET /results until ready. |
| Session cleaned up but result exists | Returns 400 with results_url. Bookmarked assessment URLs remain resolvable after the session retention window. |
Submit answer
Submits an answer and returns the next question, or completion status.
Request
| Field | Type | Required | Description |
|---|---|---|---|
question_id | string | Yes | ID of the question being answered. |
answer | string | Yes | A/B/C/D for multiple-choice, or free text for open-ended. |
response_time_ms | number | No | Milliseconds spent answering (capped at 600,000). |
Response
{
"success": true,
"is_correct": false,
"correct_answer": "C",
"explanation": "...",
"next_question": { ... },
"progress": { "questions_completed": 1, "total_questions": 20, "percent_complete": 5 },
"assessment_complete": false
}Idempotency
Open-ended response shape
{
"success": true,
"evaluation": {
"overall_score": 0.85,
"feedback": "Your explanation demonstrates excellent understanding..."
},
"next_question": { ... },
"progress": { ... },
"assessment_complete": false
}Complete response
{
"success": true,
"is_correct": true,
"correct_answer": "C",
"explanation": "...",
"assessment_complete": true,
"results_url": "/api/v1/assessments/asmt_abcdef123456/results",
"progress": { "questions_completed": 20, "total_questions": 20, "percent_complete": 100 }
}Update assessment status
Pause or resume an assessment.
Request
| Field | Type | Required | Description |
|---|---|---|---|
status | string | Yes | "paused" or "in_progress". |
Response
{
"success": true,
"assessment_id": "asmt_abcdef123456",
"status": "paused",
"resume_url": "/api/v1/assessments/asmt_abcdef123456",
"expires_at": "2025-04-07T14:30:45Z"
}Get assessment results
Returns the full results of a completed assessment.
Status-specific behavior
| Assessment status | Behavior |
|---|---|
completed | Returns results immediately. |
pending_results | Attempts to generate results; returns 202 with Retry-After: 30 if still pending. |
| Other statuses | Returns 400. |
Response
{
"success": true,
"assessment_id": "asmt_abcdef123456",
"user_id": "user_xyz789",
"organization_id": "org_abc123",
"completed_at": "2025-04-05T15:15:12Z",
"duration_minutes": 45,
"overall_score": 75.3,
"ai_literacy_level": 4,
"level_details": {
"title": "Critical Evaluator",
"description": "Proficient understanding and skilled application of AI.",
"indicators": [
"Regularly applies AI tools to solve complex problems",
"Can critically evaluate AI outputs",
"Understands technical limitations of AI systems",
"Considers ethical implications of AI use"
]
},
"dimension_scores": {
"CONCEPTUAL_KNOWLEDGE": 85.0,
"USE_APPLY_KNOWLEDGE": 75.0,
"EVALUATE_CREATE_KNOWLEDGE": 70.0,
"ETHICS_KNOWLEDGE": 65.0
},
"strengths": [ "Strong understanding of AI concepts and terminology" ],
"growth_areas": [ "Enhance awareness of AI ethics and responsible use" ],
"learning_path": {
"focus_areas": [
{ "title": "Responsible AI use", "explanation": "Learn the bias, privacy and accountability questions that matter for your work." },
{ "title": "Judging AI outputs", "explanation": "Practise checking AI-generated work for errors before you act on it." }
],
"resources": [
{
"title": "AI Ethics: Principles for Professionals",
"type": "course",
"url": "https://example.com/ai-ethics",
"relevance": "Tailored to Healthcare & Social Services. Builds ethics, bias and privacy in AI."
}
],
"next_steps": [
"Pick one AI tool you used this week and write a short note on what it got wrong.",
"Map two ethical risks from your last project and the safeguard you would add next time."
]
},
"answer_insights": {
"average_response_time_ms": 45000,
"fastest_dimension": "CONCEPTUAL_KNOWLEDGE",
"slowest_dimension": "ETHICS_KNOWLEDGE",
"consistent_errors": []
}
}Get assessment status
Lightweight status check without the current question.
{
"success": true,
"assessment_id": "asmt_abcdef123456",
"status": "in_progress",
"user_id": "user_xyz789",
"organization_id": "org_abc123",
"created_at": "2025-04-05T13:15:12Z",
"last_activity": "2025-04-05T13:25:42Z",
"progress": { "questions_completed": 8, "total_questions": 20, "percent_complete": 40 },
"expires_at": "2025-04-06T13:25:42Z"
}Organization results
Aggregated analytics for an organization.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
time_period | string | No | all_time (default), last_7_days, last_30_days, last_90_days, current_year. |
Response (abbreviated)
{
"success": true,
"organization_id": "org_abc123",
"insufficient_sample": false,
"min_group_size": 5,
"total_assessments": 25,
"completed_assessments": 23,
"incomplete_assessments": 0,
"observed_at": "2025-04-05T15:20:00Z",
"average_score": 72.5,
"average_level": 3.6,
"completion_rate": 92.0,
"dimension_averages": {
"CONCEPTUAL_KNOWLEDGE": 78.2,
"USE_APPLY_KNOWLEDGE": 75.7,
"EVALUATE_CREATE_KNOWLEDGE": 70.1,
"ETHICS_KNOWLEDGE": 65.4
},
"strongest_dimension": "CONCEPTUAL_KNOWLEDGE",
"weakest_dimension": "ETHICS_KNOWLEDGE",
"time_period": { "filter": "all_time" },
"level_distribution": { "1": 0, "2": 3, "3": 8, "4": 10, "5": 2 },
"role_analytics": { "min_group_size": 5, "suppressed": true, "groups": {} }
}Response · insufficient sample (fewer than 5 completions)
{
"success": true,
"organization_id": "org_abc123",
"insufficient_sample": true,
"min_group_size": 5,
"total_assessments": 4,
"completed_assessments": 3,
"incomplete_assessments": 0,
"completion_rate": 75,
"observed_at": "2025-04-05T15:20:00Z",
"message": "Fewer than 5 completed assessments; aggregate scores are withheld."
}Planned endpoints
Three endpoints return 501 today and are scheduled for v1.1.
| Method | Path | Purpose |
|---|---|---|
| POST | /organizations/{id}/invites | Batch invite users. |
| GET | /organizations/{id}/export | Export results. |
| POST | /webhooks | Register a webhook for assessment events. |
Reference
Dimensions & weights
Four dimensions contribute to the overall score with the weights below.
| Dimension | Weight | What it measures |
|---|---|---|
CONCEPTUAL_KNOWLEDGE | 30% | AI fundamentals, terminology, capabilities, limitations. |
USE_APPLY_KNOWLEDGE | 30% | Practical application, prompt engineering, workflow integration. |
EVALUATE_CREATE_KNOWLEDGE | 25% | Critical assessment of AI outputs, quality evaluation. |
ETHICS_KNOWLEDGE | 15% | Bias, privacy, transparency, accountability. |
Literacy levels
The overall score maps to one of five levels, each with its own learning-path profile.
| Level | Title | Range | Description |
|---|---|---|---|
| 1 | Baseline Awareness | 0 ≤ score < 20 | Basic awareness, limited practical knowledge. |
| 2 | Informed User | 20 ≤ score < 40 | Familiar with concepts, occasional tool use. |
| 3 | Capable Practitioner | 40 ≤ score < 60 | Competent understanding, regular tool use. |
| 4 | Critical Evaluator | 60 ≤ score < 80 | Proficient, can critically evaluate AI outputs. |
| 5 | AI Champion | 80 ≤ score ≤ 100 | Advanced understanding, sophisticated application. |
Adaptive testing
AILAT uses a 2-Parameter Logistic (2PL) Item Response Theory model. After each answer, the system updates the proficiency estimate and selects the next question to maximize Fisher information at that level.
Adaptive tracks
| Track | Proficiency | Difficulty mix |
|---|---|---|
| Foundational | ≤ −1.0 | Prioritizes EASY (70%) with some MEDIUM. |
| Standard | −1.0 … 1.0 | Balanced mix based on IRT. |
| Advanced | ≥ 1.0 | Prioritizes DIFFICULT (70%) with some MEDIUM. |
Error recovery
The API prioritizes assessment continuity. Most failure modes have an automatic fallback that keeps the session usable.
| Scenario | What happens |
|---|---|
| Question bank exhausted | Depends on the active instrument's generated-item policy. legacy: an LLM fallback item is generated and scored. pretest: a generated item is served unscored. closed (audited banks): the answer is kept, the session enters incomplete_inventory with blocked: true, and no literacy level is awarded. |
| LLM evaluation unavailable | The answer is recorded with evaluation.status: "failed" and contributes nothing to any score; a durable job re-evaluates it and republishes the result as a new version. A result is written as incomplete when its instrument version's scored-evidence requirements are not met. |
| Results generation fails | Status set to pending_results; retry /results later. |
| Dependency unavailable (bank metadata, storage) | Returns 503 with Retry-After; retry the same request. |
| Rate limiter unavailable | Returns 503 with Retry-After: 30. |
| Network timeout on answer | Re-submit the same answer (idempotent). |
Best practices
Session management
- Store assessment_id securely between requests.
- Retention is 7 days idle for in-progress or paused sessions and 90 days after completion; there is no automatic idle pause.
- Check expires_at to anticipate expiration.
Answer submission
- Include response_time_ms when possible for response-time analytics.
- Acceptable range: 5 – 60s for MC, 60 – 300s for open-ended.
- The same answer can be safely re-submitted (idempotent, even after completion); a different answer for the same question returns 409.
Error handling
- Retry with exponential backoff for 429 and 503.
- Use recovery_action for user-facing guidance.
- Poll on 202 for pending results.
Result visualization
- Use radar charts for dimension scores.
- Color-code literacy levels 1 – 5.
- Highlight strengths (≥ 70%) and growth areas (< 60%).
Code examples
Drop-in patterns for the two most common integration headaches.
Retry with exponential backoff
async function apiRequest(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status === 429 || response.status === 503) {
const retryAfter = response.headers.get('Retry-After') || 5;
await new Promise((r) =>
setTimeout(r, retryAfter * 1000 * Math.pow(2, i))
);
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}Poll for pending results
async function getResults(assessmentId, token) {
while (true) {
const res = await fetch(
`https://ailat.io/api/v1/assessments/${assessmentId}/results`,
{ headers: { Authorization: `Bearer ${token}` } }
);
if (res.status === 200) return res.json();
if (res.status === 202) {
const delay = res.headers.get('Retry-After') || 30;
await new Promise((r) => setTimeout(r, delay * 1000));
continue;
}
throw new Error(`Unexpected status: ${res.status}`);
}
}Support
Support
Changelog
v1.1.0
- Industry identifiers unified: the API, the question bank, the importer and the picker share one 19-value list (Academia & Education, Legal Services, Science & Research, Retail & Consumer Goods, General, …). The old labels Education, Retail & E-commerce and General (Cross-industry) are still accepted and normalized.
- Session writes are conflict-safe: creation is create-if-absent, activity and status changes are atomic, versions come only from stored state. A stale write can no longer erase an accepted answer or reopen a finished assessment (409 on conflict).
- Answer replay works in every state, including completed, and returns the bound next question; a different answer for an already-answered question returns 409.
- Served content is authoritative for scoring: retiring, editing or retyping a live bank row after it was served does not change what the participant can answer or how it is scored.
- Failed open-ended evaluations are recorded as unscored evidence (evaluation.status: failed) instead of a silent 0.5, retried durably, and republished as a new result_version.
- New terminal state incomplete_inventory for closed banks that run out of eligible items: answers are kept, GET /results returns incomplete: true and no literacy level; incomplete results are excluded from organization averages.
- Results carry provenance: instrument version, bank digest(s) served, selection and generated-item policy, scoring route, per-dimension scored and unscored counts, pretest count, evaluator availability, completion_reason and result_version.
- Organization results use cohort semantics with an observation cutoff (observed_at, completed_in_window, incomplete_assessments); windowed completion_rate is null with a note when start events do not cover the window instead of a manufactured 100%.
- Request schemas are bounded (400 with field errors for wrong types; 100-character role/department; 413 for bodies over 64 KB) and analytics grouping is safe for any label.
- Authorization is checked immediately after lookup on every participant route, so a foreign organization receives an identical 403 regardless of session state.
- The documented 30-minute automatic pause was never enforced and has been removed from the contract; pausing is client-initiated. Retention: 7 days idle, 90 days after completion.
- Post-review fixes: adaptive selection keeps the v2 evidence floor feasible for every participant; a bank outage is a 503, never inventory exhaustion; failed evaluations retry durably outside the object lock and republish automatically; GET /results returns 202 while a corrected score is unpublished; privacy erasure removes retained cohort start keys and the admin export returns every result version; completion_reason distinguishes insufficient_evidence.
v1.0.3
- Completed assessments remain viewable indefinitely — GET /assessments/{id}/results now serves directly from the immutable result record without requiring the underlying session to still exist.
- GET /assessments/{id} now redirects (400 + results_url) when the session has been cleaned up but a result still exists, so bookmarked assessment URLs continue to resolve after the retention window.
- Session retention switched from a flat 24h KV TTL to a Durable Object alarm: 7 days idle for in-progress / paused, 90 days after completion. The expires_at field on /status responses now reflects the real retention deadline.
- PUT /assessments/{id}/status now rejects pending_results in addition to completed.
- Errors now always return JSON. Previously some thrown errors fell through to a plain-text 500; clients no longer have to parse non-JSON responses.
- Internal 5xx error messages are no longer disclosed to clients — server-side detail stays in worker logs while clients receive a generic message.
- Authorization is now checked before any session-mutating helper runs on GET /assessments/{id} and POST /assessments/{id}/answers.
- Organization analytics index switched from a mutable JSON array to per-result marker keys, eliminating lost-update races on concurrent completions.
v1.0.1
- Adaptive track thresholds adjusted from ±1.5 to ±1.0 for better responsiveness.
- Adaptive track re-evaluation was announced here but shipped only as assignment on entering the adaptive phase (selection policy v1); per-answer reassignment ships as selection policy v2 with instrument v2.
- A 30-minute automatic pause was announced here but never enforced; removed from the contract in v1.1.0.
- Answer submission is idempotent (safe to retry on network timeout).
- Pending results return 202 instead of 500.
- Unimplemented endpoints return 501 with clear messaging.
- Added strongest_dimension, weakest_dimension, time_period to organization results.
- Added Cache-Control headers to results and analytics endpoints.
- Rate limiter fails closed (503) instead of silently bypassing.
- Authentication errors unified to prevent token enumeration.
v1.0.0
- Initial API release.
- Core assessment endpoints.
- Organization analytics.
- Adaptive item selection using a 2PL model.
- Learning path recommendations.
Planned for v1.1
- Batch invitations (POST /organizations/{id}/invites).
- Data export (GET /organizations/{id}/export).
- Webhook notifications (POST /webhooks).
- Enhanced organization management.