API Reference
Complete reference for the Automated Future REST API.
Base URL: https://api.automatedfuture.co/v1/test
All endpoints (except /status) require an API key passed in the Authorization header. Create one in the dashboard under Team > API Keys.
curl https://api.automatedfuture.co/v1/test/statuscurl -H "Authorization: YOUR_API_KEY" \
https://api.automatedfuture.co/v1/test/projectAuthentication
Every request must include your API key:
Authorization: YOUR_API_KEYAPI keys are scoped to a team. You can only access resources that belong to your team. Keys carry permissions based on the creating user's role — most keys have full read/write access.
Errors
| Status | Meaning |
|---|---|
401 Unauthorized | Missing or invalid API key |
403 Forbidden | Valid key but insufficient permissions |
All error responses return JSON:
{ "message": "description of what went wrong" }Status
GET /status
Health check. No authentication required.
curl https://api.automatedfuture.co/v1/test/statusResponse 200 OK
{
"status": "ok",
"version": "0.1.0"
}Returns 503 Service Unavailable if the database is unreachable.
Projects
GET /project/
List projects belonging to your team.
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
page_size | integer | 20 | Results per page (1–100) |
page_token | string | — | Cursor from a previous response for the next page |
curl -H "Authorization: YOUR_API_KEY" \
"https://api.automatedfuture.co/v1/test/project?page_size=10"Response 200 OK
{
"projects": [
{
"project_id": "project_abc123",
"name": "My Project",
"description": "End-to-end test suite",
"status": "active",
"created_at": "2025-01-15T10:30:00Z"
}
],
"page_token": null
}| Field | Type | Description |
|---|---|---|
project_id | string | Unique project identifier |
name | string | Project name (2–255 chars) |
description | string or null | Optional description (up to 1024 chars) |
status | string | active or inactive |
created_at | string | ISO 8601 timestamp |
page_token | string or null | Pass as page_token to fetch the next page; null means no more results |
Test Runs
A test run groups related test results together (e.g. a single CI pipeline execution).
POST /run/
Create a new test run.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
project_id | string | Yes | Project to create the run under |
label | string | No | Human-readable label (2–255 chars), e.g. "CI #42" |
metadata | object | No | Arbitrary JSON metadata |
curl -X POST -H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"project_id": "project_abc123", "label": "Nightly tests"}' \
https://api.automatedfuture.co/v1/test/runResponse 200 OK
{
"test_run_id": "run_xyz789"
}POST /run/
Update an existing test run.
Path parameters
| Name | Type | Description |
|---|---|---|
test_run_id | string | The run to update |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
label | string | No | New label (2–255 chars) |
status | string | No | pending, running, or completed |
metadata | object | No | Arbitrary JSON metadata |
Setting status to running records started_at. Setting status to completed records finished_at and snapshots result counts.
curl -X POST -H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "completed"}' \
https://api.automatedfuture.co/v1/test/run/run_xyz789Response 204 No Content
Test Results
A test result represents a single test case within a run.
POST /result/
Create a new test result.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
project_id | string | Yes | Project the result belongs to |
test_run_id | string | No | Test run to attach this result to |
test_name | string | Yes | Test name (2–255 chars) |
status | string | Yes | pending, running, passed, failed, skipped, or known_fail |
error_message | string | No | Error details (up to 1024 chars) |
started_at | string | No | ISO 8601 timestamp |
finished_at | string | No | ISO 8601 timestamp |
execution_time_ms | integer | No | Duration in milliseconds |
metadata | object | No | Arbitrary JSON metadata |
You can create a fully-completed test result in a single request by providing status, finished_at, and execution_time_ms up front — no need to call the start/finish endpoints separately.
curl -X POST -H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"project_id": "project_abc123",
"test_run_id": "run_xyz789",
"test_name": "test_user_login",
"status": "passed",
"execution_time_ms": 1250
}' \
https://api.automatedfuture.co/v1/test/resultResponse 200 OK
{
"test_result_id": "res_def456"
}GET /result/
Get a single test result by ID.
curl -H "Authorization: YOUR_API_KEY" \
https://api.automatedfuture.co/v1/test/result/res_def456Response 200 OK
{
"test_result": {
"test_result_id": "res_def456",
"project_id": "project_abc123",
"test_run_id": "run_xyz789",
"test_name": "test_user_login",
"status": "passed",
"error_message": null,
"metadata": null,
"started_at": "2025-01-15T10:31:00Z",
"finished_at": "2025-01-15T10:31:01Z",
"execution_time_ms": 1250,
"test_run_label": "Nightly tests"
}
}| Field | Type | Description |
|---|---|---|
test_result_id | string | Unique result identifier |
project_id | string | Parent project |
test_run_id | string or null | Parent test run |
test_name | string | Test name |
status | string | pending, running, passed, failed, skipped, or known_fail |
error_message | string or null | Error details (up to 1024 chars) |
metadata | object or null | Arbitrary JSON |
started_at | string or null | ISO 8601 start time |
finished_at | string or null | ISO 8601 finish time |
execution_time_ms | integer or null | Duration in milliseconds |
test_run_label | string or null | Label of the parent test run |
POST /result/
Update a test result.
Request body — all fields optional, only provided fields are updated.
| Field | Type | Description |
|---|---|---|
status | string | New status |
error_message | string | Error message (up to 1024 chars) |
metadata | object | Arbitrary JSON metadata |
started_at | string | ISO 8601 timestamp |
finished_at | string | ISO 8601 timestamp |
execution_time_ms | integer | Duration in milliseconds |
curl -X POST -H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "failed", "error_message": "Assertion failed", "execution_time_ms": 3200}' \
https://api.automatedfuture.co/v1/test/result/res_def456Response 200 OK
POST /result/{test_result_id}/start
Mark a test as started. Sets started_at to the current server time.
curl -X POST -H "Authorization: YOUR_API_KEY" \
https://api.automatedfuture.co/v1/test/result/res_def456/startResponse 200 OK
POST /result/{test_result_id}/finish
Mark a test as finished. Sets finished_at to the current server time and calculates execution_time_ms from started_at.
Request body — all fields optional.
| Field | Type | Description |
|---|---|---|
status | string | Final status |
error_message | string | Error message (up to 1024 chars) |
metadata | object | Arbitrary JSON metadata |
curl -X POST -H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "passed"}' \
https://api.automatedfuture.co/v1/test/result/res_def456/finishResponse 200 OK
DELETE /result/
Delete a test result and its associated artifacts.
curl -X DELETE -H "Authorization: YOUR_API_KEY" \
https://api.automatedfuture.co/v1/test/result/res_def456Response 200 OK
Artifacts
Artifacts are files attached to a test result — logs, screenshots, videos, etc. Uploading is a three-step process: create the record, upload the file to the returned presigned URL, then confirm.
GET /artifact/
List artifacts for a test result.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
test_result_id | string | Yes | The test result to list artifacts for |
curl -H "Authorization: YOUR_API_KEY" \
"https://api.automatedfuture.co/v1/test/artifact?test_result_id=res_def456"Response 200 OK
{
"artifacts": [
{
"artifact_id": "art_ghi012",
"test_result_id": "res_def456",
"project_id": "project_abc123",
"label": "screenshot.png",
"kind": "image",
"content_type": "image/png",
"size_bytes": 204800,
"test_step": null,
"metadata": null,
"expires_at": "2025-02-14T10:31:00Z",
"created_at": "2025-01-15T10:31:00Z"
}
]
}| Field | Type | Description |
|---|---|---|
artifact_id | string | Unique artifact identifier |
test_result_id | string | Parent test result |
project_id | string | Parent project |
label | string | Display label (1–255 chars) |
kind | string | log, image, video, or other |
content_type | string | MIME type |
size_bytes | integer | File size in bytes |
test_step | string or null | Optional test step name |
metadata | object or null | Arbitrary JSON |
expires_at | string | ISO 8601 expiration timestamp |
created_at | string | ISO 8601 creation timestamp |
POST /artifact/
Create an artifact record and get a presigned upload URL.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
test_result_id | string | Yes | Test result to attach the artifact to |
label | string | Yes | Display label (1–255 chars) |
kind | string | Yes | log, image, video, or other |
content_type | string | Yes | MIME type (1–255 chars) |
size_bytes | integer | Yes | File size in bytes (1–100 MB) |
test_step | string | No | Test step name |
metadata | object | No | Arbitrary JSON metadata |
Limits: Maximum 50 artifacts per test result. The test result must not be older than 7 days.
curl -X POST -H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"test_result_id": "res_def456",
"label": "server.log",
"kind": "log",
"content_type": "text/plain",
"size_bytes": 10240
}' \
https://api.automatedfuture.co/v1/test/artifactResponse 200 OK
{
"artifact_id": "art_ghi012",
"upload_url": "https://storage.example.com/presigned-put-url"
}Upload the file
Use the upload_url from the previous step to upload the file with a PUT request. No Authorization header is needed — the URL is pre-authenticated.
curl -X PUT \
-H "Content-Type: text/plain" \
--data-binary @server.log \
"https://storage.example.com/presigned-put-url"POST /artifact/{artifact_id}/confirm
Confirm that the file has been uploaded. The artifact is not visible until confirmed.
curl -X POST -H "Authorization: YOUR_API_KEY" \
https://api.automatedfuture.co/v1/test/artifact/art_ghi012/confirmResponse 200 OK
GET /artifact/{artifact_id}/download
Get a presigned download URL for an artifact.
curl -H "Authorization: YOUR_API_KEY" \
https://api.automatedfuture.co/v1/test/artifact/art_ghi012/downloadResponse 200 OK
{
"download_url": "https://storage.example.com/presigned-get-url",
"content_type": "text/plain"
}DELETE /artifact/
Delete an artifact and its stored file.
curl -X DELETE -H "Authorization: YOUR_API_KEY" \
https://api.automatedfuture.co/v1/test/artifact/art_ghi012Response 200 OK
Error Codes
| Status | Meaning |
|---|---|
400 Bad Request | Validation failed (missing field, invalid value, limit exceeded) |
401 Unauthorized | Missing or invalid API key |
403 Forbidden | Insufficient permissions or resource not accessible |
404 Not Found | Resource does not exist or belongs to a different team |
500 Internal Server Error | Unexpected server error |
503 Service Unavailable | Database unreachable (returned by /status only) |
All errors return a JSON body:
{ "message": "description of what went wrong" }Full Example
Create a test run, report a result with an artifact, and close the run:
API="https://api.automatedfuture.co/v1/test"
KEY="YOUR_API_KEY"
PROJECT="project_abc123"
# 1. Create a test run
RUN_ID=$(curl -s -X POST -H "Authorization: $KEY" \
-H "Content-Type: application/json" \
-d "{\"project_id\": \"$PROJECT\", \"label\": \"Manual run\"}" \
"$API/run" | jq -r '.test_run_id')
# 2. Create a test result
RESULT_ID=$(curl -s -X POST -H "Authorization: $KEY" \
-H "Content-Type: application/json" \
-d "{\"project_id\": \"$PROJECT\", \"test_run_id\": \"$RUN_ID\", \"test_name\": \"test_login\", \"status\": \"passed\", \"execution_time_ms\": 420}" \
"$API/result" | jq -r '.test_result_id')
# 3. Upload a log artifact
ARTIFACT=$(curl -s -X POST -H "Authorization: $KEY" \
-H "Content-Type: application/json" \
-d "{\"test_result_id\": \"$RESULT_ID\", \"label\": \"output.log\", \"kind\": \"log\", \"content_type\": \"text/plain\", \"size_bytes\": $(wc -c < output.log)}" \
"$API/artifact" )
UPLOAD_URL=$(echo "$ARTIFACT" | jq -r '.upload_url')
ART_ID=$(echo "$ARTIFACT" | jq -r '.artifact_id')
curl -X PUT -H "Content-Type: text/plain" --data-binary @output.log "$UPLOAD_URL"
curl -X POST -H "Authorization: $KEY" "$API/artifact/$ART_ID/confirm"
# 4. Complete the test run
curl -X POST -H "Authorization: $KEY" \
-H "Content-Type: application/json" \
-d '{"status": "completed"}' \
"$API/run/$RUN_ID"