API reference
REST-style HTTP API for projects, sources, review templates, and reviews using Clearly AI API keys.
Use the Clearly AI API to list review templates, create Projects, upload sources, start Reviews, and fetch Review status and results.
Related pages: CLI, Workflows, Jira, Exports, Review template schema.
Authentication
Create a personal API key in the Clearly AI web app:
- Open Settings.
- Under Manage, open Personal API Keys.
- Create a key and copy it. Store it securely; you may not be able to view it again.
Send the key as a Bearer token on every API request:
curl -sS \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
"https://{tenant}.clearly-app.com/api/v1/projects"If your key is missing, invalid, or does not have access to the requested Organization or Project, the API returns 401 or 403.
Base URL
Use the API host provided for your Clearly AI deployment. It typically uses your tenant subdomain:
https://{tenant}.clearly-app.comReplace {tenant} with your Clearly AI tenant name. All endpoint paths below are relative to that host.
Make your first request
curl -sS \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
"https://{tenant}.clearly-app.com/api/v1/questionnaires"A successful response returns the active Review Templates your Organization can use.
Prefer the command line for this flow? See CLI.
Core endpoints
Bodies and responses are JSON unless noted otherwise.
List review templates
| Method / path | GET /api/v1/questionnaires |
| Purpose | List active Review Template versions. |
curl -sS \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
"https://{tenant}.clearly-app.com/api/v1/questionnaires"[
{
"name": "Security Review",
"filename": "security_review.yaml",
"version": 1,
"title": "Security Review",
"description": "A comprehensive security assessment"
}
]Get a review template
| Method / path | GET /api/v1/questionnaires/{filename} |
| Purpose | Get the active version of one Review Template as JSON. |
curl -sS \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
"https://{tenant}.clearly-app.com/api/v1/questionnaires/security_review.yaml"The response is the parsed template: metadata, blocks, name, path, and version. The version is also returned in the X-Clearly-Version header.
Use GET /api/v1/questionnaires/{filename}/file to download the same template as canonical YAML instead.
A single Review Template includes hidden_instructions, so these routes require an API key whose owner has Review Template access. The list route returns names, titles, and descriptions only, so it stays available to everyone.
Validate a review template
| Method / path | POST /api/v1/questionnaires/{filename}/validate |
| Body | yaml (string, required). |
Parses the YAML and reports what would happen, without saving anything.
curl -sS -X POST \
"https://{tenant}.clearly-app.com/api/v1/questionnaires/security_review.yaml/validate" \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"yaml":"metadata:\n title: Security Review\nblocks: []\n"}'{
"operation": "updated",
"version": 4,
"dryRun": true,
"questionnaire": { "metadata": {}, "blocks": [] }
}Invalid YAML returns 400 with a message describing the problem. Use /validate/file to get canonical YAML back instead of JSON.
Create or update a review template
| Method / path | PUT /api/v1/questionnaires/{filename} |
| Body | yaml (string, required), dryRun (boolean, optional). |
curl -sS -X PUT \
"https://{tenant}.clearly-app.com/api/v1/questionnaires/security_review.yaml" \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"yaml":"metadata:\n title: Security Review\nblocks: []\n"}'A new filename creates version 1 and returns "operation": "created". An existing filename creates the next version and returns "operation": "updated". Existing Reviews keep the version they ran with.
Responses carry X-Clearly-Version, X-Clearly-Operation, and X-Clearly-Dry-Run headers. Use PUT /api/v1/questionnaires/{filename}/file to get canonical YAML back instead of JSON.
Upload a review template file
| Method / path | POST /api/v1/questionnaires/{filename}/upload-url |
| Body | operation (validate or upsert, default validate), format (json or yaml, default json). |
Returns a short-lived URL for sending a YAML file directly, so you never have to inline the file in a JSON body.
{
"upload_url": "https://{tenant}.clearly-app.com/api/backend/v1/mcp/upload-review-template?...",
"method": "POST",
"content_type": "multipart/form-data",
"file_field": "file",
"expires_in_seconds": 300,
"instructions": "POST the YAML file as multipart/form-data in the 'file' field. ..."
}POST the file to that URL within the expiry window:
curl -sS -X POST "$UPLOAD_URL" -F "file=@./security_review.yaml"The upload response matches the validate or upsert response for the format you requested. The URL is bound to the requesting user, organization, filename, operation, and response format, so it cannot be reused for a different template.
Create a project
| Method / path | POST /api/v1/projects |
| Body | name (string, required), description (string, optional). |
curl -sS -X POST \
"https://{tenant}.clearly-app.com/api/v1/projects" \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Production API Security Review","description":"Scope: public API and workers."}'{
"id": "9020317",
"name": "Production API Security Review",
"description": "Scope: public API and workers.",
"creator": { "email": "chris@example.com" },
"projectCreationTime": 1767742167512,
"lastModifiedTime": 1767742177360.6138,
"stage": "Draft",
"tags": []
}Use the returned id as the Project identifier in other Project routes.
List projects
| Method / path | GET /api/v1/projects |
| Purpose | List Projects the API key can access. |
curl -sS \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
"https://{tenant}.clearly-app.com/api/v1/projects"Get project details
| Method / path | GET /api/v1/projects/{projectId} |
| Path parameter | projectId - Project ID returned by create or list routes. |
curl -sS \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
"https://{tenant}.clearly-app.com/api/v1/projects/9020317"The response includes Project metadata and related Review metadata.
Update a project
| Method / path | PATCH /api/v1/projects/{projectId} |
| Body | name (string, optional), description (string, optional). |
curl -sS -X PATCH \
"https://{tenant}.clearly-app.com/api/v1/projects/9020317" \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"description":"Updated scope."}'Delete a project
| Method / path | DELETE /api/v1/projects/{projectId} |
curl -sS -X DELETE \
"https://{tenant}.clearly-app.com/api/v1/projects/9020317" \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY"A successful response returns { "success": true }.
Upload sources to a project
| Method / path | POST /api/v1/projects/{projectId}/sources/files |
| Content type | multipart/form-data |
| Form fields | files - one or more file parts. collection_type - optional: CODE, DOCUMENTS, or AUTODETECT. |
curl -sS -X POST \
"https://{tenant}.clearly-app.com/api/v1/projects/9020317/sources/files" \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
-F "files=@./architecture.pdf" \
-F "collection_type=AUTODETECT"{
"sources": [
{
"fileSourceId": "kx712xps3049pg14bjd76h1snx7ypeyf",
"filename": "architecture.pdf",
"size": 102400
}
]
}Uploading sources requires edit access to the Project.
Trigger a review
| Method / path | POST /api/v1/projects/{projectId}/reviews |
| Body | questionnaireFilename (string, required). |
curl -sS -X POST \
"https://{tenant}.clearly-app.com/api/v1/projects/9020317/reviews" \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"questionnaireFilename":"basic-vendor-questionnaire.yaml"}'{
"reviewId": "jx712xps3049pg14bjd76h1snx7ypeyf",
"taskId": "kx7d27k3sv39231bacf6r4apds7yq1zy",
"taskRunId": "mx7d27k3sv39231bacf6r4apds7yq1zy"
}Upload sources first, then create the Review so generation has material to cite.
Get review status and results
| Method / path | GET /api/v1/reviews/{reviewId} |
curl -sS \
-H "Authorization: Bearer YOUR_PERSONAL_API_KEY" \
"https://{tenant}.clearly-app.com/api/v1/reviews/jx712xps3049pg14bjd76h1snx7ypeyf"Poll until lastStatus is Generated and failureReason is absent. Until then, answer blocks may be omitted or incomplete.
{
"reviewId": "jx712xps3049pg14bjd76h1snx7ypeyf",
"createdAt": 1768494552856.2966,
"lastStatus": "Generated",
"lastStatusUpdatedAt": 1768494706924,
"creator": { "email": "chris@example.com" },
"questionnaire": {
"questionnaireId": "k574yc8w5tp95kkpgsw1fmh5957v72g1",
"name": "Basic Vendor Review"
},
"blocks": [
{
"text": "Does the vendor maintain an information security policy?",
"block_type": "yes_no",
"answer": {
"answerId": "...",
"status": "active",
"confidence": "high",
"complianceStatus": "compliant",
"complianceExplanation": "...",
"contentString": "Yes. The submitted policy covers ...",
"explanationString": "Evidence includes ..."
}
}
]
}Export review data
For downloadable export formats such as Markdown, HTML, PDF, Word, CSV, and XLSX, use the export flow documented in Exports. Full structured Review answers are available as JSON from GET /api/v1/reviews/{reviewId} after generation completes.
Webhooks
Inbound webhook endpoints are configured through Clearly AI integrations and Workflow setup. They use integration-specific secrets, not personal API keys.
For event-driven automation, use Workflows. If your integration does not expose a webhook event for your use case, poll GET /api/v1/reviews/{reviewId} for Review completion.
Pagination
| Endpoint | Behavior |
|---|---|
GET /api/v1/projects | Returns all active Projects the API key can access. |
GET /api/v1/questionnaires | Returns the full active Review Template list. |
GET /api/v1/reviews/{reviewId} | Returns a single Review object. |
Limits
Upload and response limits depend on your Clearly AI deployment. For large files or bulk imports, split requests and retry transient failures with backoff.
Error reference
Responses are typically JSON with an error field and, when available, a message field.
| HTTP | Common cause | What to do |
|---|---|---|
400 | Invalid request body, bad multipart upload, or missing required field. | Fix the request shape and retry. |
401 | Missing or invalid Authorization header. | Confirm the Bearer token is present and active. |
403 | API key is valid but does not have access to the Organization, Project, or operation. | Confirm the key owner has the required access. |
404 | Unknown Project ID, Review Template filename, or Review ID. | Confirm IDs and filenames. |
500 | Unexpected server error. | Retry with backoff or contact support with the response body and request timestamp. |