Download OpenAPI specification:
A solution to enable remote state for Terraform and OpenTofu that offers a "does one job well" approach to state storage and locking.
This API provides:
FreeState's API is split into two separate specifications:
Main Backend API (this specification):
Portal Management API:
This separation ensures:
This API supports both path-based and Accept header-based versioning:
Path-based versioning (current):
/api/v1/... - Version 1 endpointsAccept header versioning (recommended):
Accept: application/vnd.freestate.v1+json - Version 1Accept: application/vnd.freestate.v2+json - Version 2Response headers:
FreeState-API-Version - Indicates the API version being usedDeprecation - Present when using a deprecated versionSunset - Date when deprecated version will be removedWarning - Deprecation warning messageDefault behavior:
Returns the health status of the service and database connectivity
| FreeState-API-Version | string Example: "v1" The API version being used for this response |
| status required | string Enum: "healthy" "unhealthy" |
| uptime | string Service uptime |
| version | string Application version |
{- "status": "healthy",
- "version": "string",
- "uptime": "string"
}Login with username and password to receive an authentication token
| password required | string non-empty |
| username required | string non-empty |
| expires_at required | string <date-time> Token expiration time |
| token required | string JWT authentication token |
required | object (UserInfo) |
{- "username": "string",
- "password": "string"
}{- "token": "string",
- "user": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "username": "string",
- "email": "user@example.com",
- "organization": "string",
- "role": "admin"
}, - "expires_at": "2019-08-24T14:15:22Z"
}Create a new organization with specified plan limits
| name required | string non-empty ^[a-zA-Z0-9]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$ |
| plan | string Default: "free" Enum: "free" "pro" "enterprise" |
| active required | boolean |
| created_at required | string <date-time> |
| id required | string <uuid> |
| max_state_size required | integer <int64> Maximum state size in bytes |
| max_users required | integer Maximum number of users allowed |
| max_workspaces required | integer Maximum number of workspaces allowed |
| name required | string |
| plan required | string Enum: "free" "pro" "enterprise" |
| updated_at required | string <date-time> |
{- "name": "string",
- "plan": "free"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "plan": "free",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "active": true,
- "max_workspaces": 0,
- "max_state_size": 0,
- "max_users": 0
}Bootstrap endpoint for creating the first admin user in an organization
| email required | string <email> |
| organization required | string non-empty |
| password required | string >= 8 characters |
| role | string Default: "user" Enum: "admin" "user" |
| username required | string non-empty |
| active required | boolean |
| created_at required | string <date-time> |
| email required | string <email> |
| id required | string <uuid> |
| organization required | string |
| role required | string Enum: "admin" "user" |
| updated_at required | string <date-time> |
| username required | string |
{- "username": "string",
- "email": "user@example.com",
- "password": "stringst",
- "organization": "string",
- "role": "admin"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "username": "string",
- "email": "user@example.com",
- "organization": "string",
- "role": "admin",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "active": true
}Create a new user in the organization (requires admin role)
| email required | string <email> |
| organization required | string non-empty |
| password required | string >= 8 characters |
| role | string Default: "user" Enum: "admin" "user" |
| username required | string non-empty |
| active required | boolean |
| created_at required | string <date-time> |
| email required | string <email> |
| id required | string <uuid> |
| organization required | string |
| role required | string Enum: "admin" "user" |
| updated_at required | string <date-time> |
| username required | string |
{- "username": "string",
- "email": "user@example.com",
- "password": "stringst",
- "organization": "string",
- "role": "admin"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "username": "string",
- "email": "user@example.com",
- "organization": "string",
- "role": "admin",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "active": true
}Get information about the currently authenticated user
| active required | boolean |
| created_at required | string <date-time> |
| email required | string <email> |
| id required | string <uuid> |
| organization required | string |
| role required | string Enum: "admin" "user" |
| updated_at required | string <date-time> |
| username required | string |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "username": "string",
- "email": "user@example.com",
- "organization": "string",
- "role": "admin",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "active": true
}Create a new API key for authentication
| expires_at | string or null <date-time> |
| name required | string non-empty |
| created_at required | string <date-time> |
| expires_at | string or null <date-time> |
| id required | string <uuid> |
| key required | string The actual API key (only returned once) |
| name required | string |
{- "name": "string",
- "expires_at": "2019-08-24T14:15:22Z"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "key": "string",
- "name": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}List all API keys for the current user
| active required | boolean |
| created_at required | string <date-time> |
| expires_at | string or null <date-time> |
| id required | string <uuid> |
| name required | string |
| organization required | string |
| user_id required | string <uuid> |
[- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
- "organization": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z",
- "active": true
}
]List all workspaces in the organization
| created_at required | string <date-time> |
| id required | string <uuid> |
| lock_id | string or null |
object (LockInfo) | |
| locked required | boolean |
| name required | string |
| organization required | string |
| updated_at required | string <date-time> |
[- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "organization": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "locked": true,
- "lock_id": "string",
- "lock_info": {
- "ID": "string",
- "Operation": "string",
- "Info": "string",
- "Who": "string",
- "Version": "string",
- "Created": "2019-08-24T14:15:22Z",
- "Path": "string"
}
}
]Create a new workspace in the organization
| name required | string non-empty ^[a-zA-Z0-9]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$ |
| created_at required | string <date-time> |
| id required | string <uuid> |
| lock_id | string or null |
object (LockInfo) | |
| locked required | boolean |
| name required | string |
| organization required | string |
| updated_at required | string <date-time> |
{- "name": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "organization": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "locked": true,
- "lock_id": "string",
- "lock_info": {
- "ID": "string",
- "Operation": "string",
- "Info": "string",
- "Who": "string",
- "Version": "string",
- "Created": "2019-08-24T14:15:22Z",
- "Path": "string"
}
}Get information about a specific workspace
| name required | string Workspace name |
| created_at required | string <date-time> |
| id required | string <uuid> |
| lock_id | string or null |
object (LockInfo) | |
| locked required | boolean |
| name required | string |
| organization required | string |
| updated_at required | string <date-time> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "organization": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "locked": true,
- "lock_id": "string",
- "lock_info": {
- "ID": "string",
- "Operation": "string",
- "Info": "string",
- "Who": "string",
- "Version": "string",
- "Created": "2019-08-24T14:15:22Z",
- "Path": "string"
}
}Get the current Terraform state for a workspace (Terraform HTTP Backend protocol)
| organization required | string Organization name |
| workspace required | string Workspace name |
Terraform state data
{ }Update the Terraform state for a workspace (Terraform HTTP Backend protocol)
| organization required | string Organization name |
| workspace required | string Workspace name |
| ID | string Lock ID for state locking |
Terraform state data
{ }{- "error": "string"
}Delete the Terraform state for a workspace (Terraform HTTP Backend protocol)
| organization required | string Organization name |
| workspace required | string Workspace name |
{- "error": "string"
}Lock the Terraform state for a workspace to prevent concurrent modifications (Terraform HTTP Backend protocol using standard REST methods - preferred for new implementations)
| organization required | string Organization name |
| workspace required | string Workspace name |
| Created required | string <date-time> When the lock was created |
| ID required | string Unique lock identifier |
| Info required | string Additional information about the lock |
| Operation required | string Operation being performed |
| Path required | string State path |
| Version required | string Terraform version |
| Who required | string User who created the lock |
| Created required | string <date-time> When the lock was created |
| ID required | string Unique lock identifier |
| Info required | string Additional information about the lock |
| Operation required | string Operation being performed |
| Path required | string State path |
| Version required | string Terraform version |
| Who required | string User who created the lock |
{- "ID": "string",
- "Operation": "string",
- "Info": "string",
- "Who": "string",
- "Version": "string",
- "Created": "2019-08-24T14:15:22Z",
- "Path": "string"
}{- "ID": "string",
- "Operation": "string",
- "Info": "string",
- "Who": "string",
- "Version": "string",
- "Created": "2019-08-24T14:15:22Z",
- "Path": "string"
}Unlock the Terraform state for a workspace (Terraform HTTP Backend protocol using standard REST methods - preferred for new implementations)
| organization required | string Organization name |
| workspace required | string Workspace name |
| ID required | string Lock ID to verify unlock authorization |
{- "ID": "string"
}{- "error": "string"
}List all versions of state for a workspace
| organization required | string Organization name |
| workspace required | string Workspace name |
| created_at required | string <date-time> |
| created_by | string or null <uuid> |
| hash required | string |
| id required | string <uuid> |
| size required | integer <int64> |
| version required | integer |
[- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "version": 0,
- "size": 0,
- "hash": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4"
}
]Get a specific version of state for a workspace
| organization required | string Organization name |
| version required | integer State version number |
| workspace required | string Workspace name |
| created_at required | string <date-time> |
| created_by | string or null <uuid> |
| hash required | string |
| id required | string <uuid> |
| size required | integer <int64> |
| state_data | object The actual Terraform state data |
| version required | integer |
| workspace_id required | string <uuid> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
- "version": 0,
- "size": 0,
- "hash": "string",
- "state_data": { },
- "created_at": "2019-08-24T14:15:22Z",
- "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4"
}Compare two versions of state and return the differences
| organization required | string Organization name |
| workspace required | string Workspace name |
| from required | integer Source version number |
| to required | integer Target version number |
| created_at required | string <date-time> |
| diff required | object Structured difference between state versions |
| from_version required | integer |
| summary required | string Human-readable summary of changes |
| to_version required | integer |
{- "from_version": 0,
- "to_version": 0,
- "diff": { },
- "summary": "string",
- "created_at": "2019-08-24T14:15:22Z"
}Rollback workspace state to a specific version
| organization required | string Organization name |
| version required | integer Version to rollback to |
| workspace required | string Workspace name |
| created_at required | string <date-time> |
| created_by | string or null <uuid> |
| hash required | string |
| id required | string <uuid> |
| size required | integer <int64> |
| state_data | object The actual Terraform state data |
| version required | integer |
| workspace_id required | string <uuid> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
- "version": 0,
- "size": 0,
- "hash": "string",
- "state_data": { },
- "created_at": "2019-08-24T14:15:22Z",
- "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4"
}Get the current encryption configuration and status for an organization
| organization required | string Organization name |
| FreeState-API-Version | string Example: "v1" The API version being used for this response |
| byok_enabled required | boolean Whether customer-provided BYOK is active |
| encryption_enabled required | boolean Whether envelope encryption is enabled |
| encryption_enabled_at | string or null <date-time> |
| kek_id | string Current KEK identifier (ARN or logical ID) |
| kek_status | string Enum: "active" "rotating" "deprecated" "disabled" KEK status |
| key_type | string Enum: "managed" "byok" Key type (managed or byok) |
| kms_provider | string Enum: "aws-kms" "azure-keyvault" "gcp-kms" "local" KMS provider (aws-kms, azure-keyvault, gcp-kms, local) |
| organization_id required | string <uuid> |
{- "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
- "encryption_enabled": true,
- "byok_enabled": true,
- "encryption_enabled_at": "2019-08-24T14:15:22Z",
- "kek_id": "string",
- "kms_provider": "aws-kms",
- "key_type": "managed",
- "kek_status": "active"
}Configure customer-provided KMS key for envelope encryption. This enables BYOK mode where the customer controls the KEK. All workspace DEKs will be re-encrypted with the new BYOK KEK.
| organization required | string Organization name |
| kek_id required | string Customer-provided KEK identifier (AWS KMS ARN, Azure Key Vault key ID, or GCP KMS key path) |
| kms_provider required | string Enum: "aws-kms" "azure-keyvault" "gcp-kms" KMS provider type |
object Optional provider-specific metadata (e.g., region, resource group) |
| FreeState-API-Version | string Example: "v1" The API version being used for this response |
| kek_id required | string |
| message required | string |
| organization_id required | string <uuid> |
| rotation_duration | string Time taken to complete the rotation (e.g., "2.5s") |
| success required | boolean |
| workspaces_reencrypted required | integer Number of workspaces that had their DEKs re-encrypted |
{- "kek_id": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012",
- "kms_provider": "aws-kms",
- "metadata": { }
}{- "success": true,
- "message": "string",
- "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
- "kek_id": "string",
- "workspaces_reencrypted": 0,
- "rotation_duration": "string"
}Remove customer-provided KMS key and revert to FreeState-managed encryption. All workspace DEKs will be re-encrypted with a new FreeState-managed KEK.
| organization required | string Organization name |
| FreeState-API-Version | string Example: "v1" The API version being used for this response |
| message required | string |
| new_kek_id required | string New FreeState-managed KEK ID |
| organization_id required | string <uuid> |
| rotation_duration | string Time taken to complete the rotation |
| success required | boolean |
| workspaces_reencrypted required | integer Number of workspaces that had their DEKs re-encrypted |
{- "success": true,
- "message": "string",
- "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
- "new_kek_id": "string",
- "workspaces_reencrypted": 0,
- "rotation_duration": "string"
}Validate that FreeState can access the customer-provided KMS key. This should be called before configuring BYOK to ensure proper setup.
| organization required | string Organization name |
| kek_id required | string KEK identifier to validate |
| kms_provider required | string Enum: "aws-kms" "azure-keyvault" "gcp-kms" KMS provider type |
object Optional provider-specific metadata |
| FreeState-API-Version | string Example: "v1" The API version being used for this response |
| kek_id | string |
| kms_provider | string |
| message required | string Validation result message |
| valid required | boolean Whether the KEK is accessible and valid |
{- "kek_id": "string",
- "kms_provider": "aws-kms",
- "metadata": { }
}{- "valid": true,
- "message": "string",
- "kek_id": "string",
- "kms_provider": "string"
}Rotate the organization's KEK. All workspace DEKs will be re-encrypted with the new KEK. This operation does not re-encrypt workspace state data. For BYOK customers, provide a new KEK ID. For managed encryption, a new FreeState-managed KEK will be generated automatically.
| organization required | string Organization name |
object Optional provider-specific metadata | |
| new_kek_id | string or null Optional new KEK ID for BYOK customers. If not provided for managed encryption, a new KEK will be automatically generated. |
| FreeState-API-Version | string Example: "v1" The API version being used for this response |
| completed_at required | string <date-time> |
| duration required | string Duration of the rotation operation (e.g., "3.2s") |
| errors | Array of strings List of any errors encountered during rotation |
| message required | string |
| new_kek_id required | string |
| old_kek_id required | string |
| started_at required | string <date-time> |
| success required | boolean |
| workspaces_rotated required | integer Number of workspaces that had their DEKs re-encrypted |
{- "new_kek_id": "string",
- "metadata": { }
}{- "success": true,
- "message": "string",
- "old_kek_id": "string",
- "new_kek_id": "string",
- "workspaces_rotated": 0,
- "duration": "string",
- "started_at": "2019-08-24T14:15:22Z",
- "completed_at": "2019-08-24T14:15:22Z",
- "errors": [
- "string"
]
}Get audit log of all encryption operations for an organization, including KEK rotations, BYOK configuration changes, and DEK operations.
| organization required | string Organization name |
| limit | integer [ 1 .. 1000 ] Default: 100 Maximum number of audit entries to return (default 100, max 1000) |
| offset | integer >= 0 Default: 0 Number of audit entries to skip (for pagination) |
| FreeState-API-Version | string Example: "v1" The API version being used for this response |
required | Array of objects (EncryptionAuditEntry) |
| limit required | integer Number of entries returned in this response |
| offset required | integer Offset used for this response |
| total required | integer Total number of audit entries available |
{- "entries": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "timestamp": "2019-08-24T14:15:22Z",
- "operation": "kek_provisioned",
- "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
- "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
- "actor": "string",
- "kek_id": "string",
- "status": "success",
- "details": { },
- "error_message": "string"
}
], - "total": 0,
- "limit": 0,
- "offset": 0
}