API Reference
Manage workspaces, upload specs, and interact with mock data through the Testfly REST API.
Base URL: https://api.testfly.com
Interactive docs available at /scalar/v1 on the running API.
Authentication
All platform API endpoints require authentication. Testfly supports two methods:
API Key (recommended for CI/scripts)
Pass your API key in the X-API-Key header:
curl -H "X-API-Key: tfk_your_api_key_here" \
https://api.testfly.com/api/workspaces
JWT Bearer Token (for portal/browser)
Include the bearer token from login:
curl -H "Authorization: Bearer eyJhbG..." \
https://api.testfly.com/api/workspaces
Create API keys from the Testfly portal under Settings → API Keys.
Workspaces
Workspaces are isolated mock API environments. Each workspace gets its own subdomain, database, and configuration.
Create workspace
POST /api/workspaces
{
"name": "Pet Store Mock",
"slug": "petstore",
"rowCount": 1000,
"seedValue": 42
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name |
slug | string | Yes | URL-safe identifier. Becomes your subdomain: {slug}.mock.testfly.com |
rowCount | integer | No | Rows per resource table. Default: 100. Range: 1–10,000 |
seedValue | integer | No | Random seed for reproducible data. Same seed = identical data every time |
Response 201 Created:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Pet Store Mock",
"slug": "petstore",
"subdomain": "petstore",
"status": "Provisioning",
"rowCount": 1000,
"seedValue": 42,
"settings": null,
"createdBy": "...",
"createdAt": "2026-02-17T10:00:00Z",
"updatedAt": "2026-02-17T10:00:00Z"
}
List workspaces
GET /api/workspaces
Returns all workspaces for the authenticated organization.
Get workspace
GET /api/workspaces/{id}
Update workspace
PUT /api/workspaces/{id}
{
"name": "Updated Name",
"rowCount": 10000,
"settings": {
"latencyMs": 200,
"errorRate": 0.05,
"corsOrigins": ["https://app.example.com"],
"authEnabled": false
}
}
| Setting | Type | Default | Description |
|---|---|---|---|
latencyMs | integer | 0 | Artificial response delay in milliseconds |
errorRate | float | 0.0 | Random 500 error probability (0.0–1.0). Set to 0.1 for 10% failure rate |
corsOrigins | string[] | [] | Allowed CORS origins |
authEnabled | boolean | false | Require authentication on mock endpoints |
Delete workspace
DELETE /api/workspaces/{id}
Marks workspace as deleted and cleans up the SQLite database. Returns 204 No Content.
Regenerate data
POST /api/workspaces/{id}/regenerate
Drops all mock data and regenerates from the active spec. Useful for resetting between test runs. Respects current rowCount and seedValue.
Pause / Resume
POST /api/workspaces/{id}/pause
POST /api/workspaces/{id}/resume
Paused workspaces return 503 for all mock requests. Resume to re-activate.
Usage stats
GET /api/workspaces/{id}/usage
Returns daily request counts and bandwidth for the workspace.
Workspace status lifecycle
Provisioning → Active → Paused → Active
↓ Error (if spec processing fails)
Specs
Upload OpenAPI specs to define the schema for your mock API. Each workspace can have multiple spec versions; only one can be active at a time.
Upload spec
POST /api/workspaces/{wid}/specs
{
"rawSpec": "openapi: '3.0.0'\ninfo:\n title: Pet Store\n ...",
"versionLabel": "v1.0"
}
| Field | Type | Required | Description |
|---|---|---|---|
rawSpec | string | Yes | Full OpenAPI spec as YAML or JSON string |
versionLabel | string | No | Version label (e.g., "v1.0"). Defaults to "v1" |
Response 201 Created. The spec starts with status Pending and transitions to Ready after background processing.
List specs
GET /api/workspaces/{wid}/specs
Get spec
GET /api/workspaces/{wid}/specs/{id}
Delete spec
DELETE /api/workspaces/{wid}/specs/{id}
Spec status lifecycle
Pending → Parsing → Ready
↓ Error (with errorMessage)
Resources & Routes
After a spec is processed, Testfly extracts resources (database tables), routes (API endpoints), and relationships (foreign keys). These are read-only — derived from your spec.
List resources
GET /api/workspaces/{wid}/specs/{id}/resources
[
{
"id": "...",
"schemaName": "Pet",
"tableName": "pets",
"routeBasePath": "/pets",
"sortOrder": 1,
"rowCountOverride": null
},
{
"id": "...",
"schemaName": "User",
"tableName": "users",
"routeBasePath": "/users",
"sortOrder": 0
}
]
sortOrder reflects the topological sort — parent tables first.
List routes
GET /api/workspaces/{wid}/specs/{id}/routes
[
{
"httpMethod": "GET",
"pathTemplate": "/pets",
"operationId": "listPets",
"responseStatusCode": 200,
"isCollection": true
},
{
"httpMethod": "POST",
"pathTemplate": "/pets",
"operationId": "createPet",
"responseStatusCode": 201,
"isCollection": false
}
]
List relationships
GET /api/workspaces/{wid}/specs/{id}/relationships
[
{
"sourceColumn": "owner_id",
"targetColumn": "id",
"relationshipType": "ManyToOne"
}
]
Mock API (CRUD)
Once a workspace is Active, your mock API is live. Access it via subdomain or path prefix:
# Subdomain (production)
https://petstore.mock.testfly.com/pets
# Path prefix (development)
https://api.testfly.com/mock/petstore/pets
List records (paginated)
GET /pets?page=1&pageSize=20&sortBy=name&sortDesc=true&species=cat
{
"data": [
{
"id": "a1b2c3d4",
"name": "Luna",
"species": "cat",
"owner_id": "u_7f8e9d"
}
],
"meta": {
"page": 1,
"pageSize": 20,
"totalCount": 47,
"totalPages": 3
}
}
| Param | Type | Default | Description |
|---|---|---|---|
page | int | 1 | Page number (1-indexed) |
pageSize | int | 20 | Results per page (max 100) |
sortBy | string | — | Column name to sort by |
sortDesc | bool | false | Sort descending |
| any other | string | — | Filter: ?status=active |
Get single record
GET /pets/{id}
{ "id": "a1b2c3d4", "name": "Luna", "species": "cat", "owner_id": "u_7f8e9d" }
Returns 404 with {"error": "Resource not found"} if not found.
Create record
POST /pets
Content-Type: application/json
{ "name": "Bella", "species": "dog", "owner_id": "u_7f8e9d" }
Returns 201 Created with auto-generated UUID id and Location header.
Update record
PUT /pets/{id}
Content-Type: application/json
{ "name": "Bella Mae" }
Partial updates supported. Returns 200 or 404.
Delete record
DELETE /pets/{id}
Returns 204 No Content or 404.
Errors
All errors return a JSON body:
{ "error": "Human-readable error message" }
| Code | Meaning |
|---|---|
400 | Bad request (malformed JSON, invalid parameters) |
401 | Missing or invalid authentication |
403 | Not authorized for this organization/workspace |
404 | Resource not found |
405 | Method not allowed on this route |
500 | Server error (or simulated error if errorRate configured) |
503 | Workspace is paused or provisioning |
Try it now
Create a free workspace and start making API calls in minutes.